哈哈, 之前 5 章看起来还真是 Boring ,这一章的名称中虽然有 Boring 但是内容却是很有趣的。
这里的 Protocols 我觉得应该指的是 Interface
接着上一章节的最后代码继续讲解。
这次将 remFn substFn 放入到参数的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | abstract class PieD {
abstract PieD rem(RemV remFn, Object o);
abstract PieD subst(SubstV substFn, Object n, Object o);
}
class Top extends PieD {
Object t;
PieD r;
Top(Object _t, PieD _r) {
t = _t;
r = _r;
}
PieD rem(RemV remFn, Object o) {
return remFn.forTop(t, r, o);
}
PieD subst(SubstV substFn, Object n, Object o) {
return sbustFn.forTop(t, r, n, o);
}
}
class Bot extends PieD {
Object t;
PieD r;
Bot(Object _t, PieD _r) {
t = _t;
r = _r;
}
PieD rem(RemV remFn, Object o) {
return remFn.forBot(t, r, o);
}
PieD subst(SubstV substFn, Object n, Object o) {
return sbustFn.forBot(t, r, n, o);
}
}
|
同步修改对应的访问者类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class RemV {
PieD forBot(Object o){
return new Bot();
}
PieD forTop(Object t, PieD r, Object o){
if (o.equals(t))
return r.rem(this, o);
else
return new Top(t, r.rem(this, o));
}
}
class SubstV {
PieD forBot(Object n, Object o){
return new Bot();
}
PieD forTop(Object t, PieD r, Object n, Object o){
if (o.equals(t))
return new Top(n, r.subst(tis, n, o));
else
return new Top(t, r.subst(this, n, o));
}
}
|
再修改访问者类,将更多的参数传入到访问者类中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | class RemV {
Object o;
RemV(Object _o) {
o = _o;
}
PieD forBot(Object o){
return new Bot();
}
PieD forTop(Object t, PieD r){
if (o.equals(t))
return r.rem(this);
else
return new Top(t, r.rem(this));
}
}
class SubstV {
Object n;
Object o;
SubstV(Object _n, Object _o){
n = _n;
o = _o;
}
PieD forBot(Object n, Object o){
return new Bot();
}
PieD forTop(Object t, PieD r){
if (o.equals(t))
return new Top(n, r.subst(this));
else
return new Top(t, r.subst(this));
}
}
|
上面的形式就很像函数式编程里面的 闭包 概念了。
好了,根据上面修改后的 SubstV ,重新修改一下 PieD 及其 Bot 和 Top
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | abstract class PieD {
abstract PieD rem(RemV remFn);
abstract PieD subst(SubstV substFn);
}
class Top extends PieD {
Object t;
PieD r;
Top(Object _t, PieD _r) {
t = _t;
r = _r;
}
PieD rem(RemV remFn) {
return remFn.forTop(t, r);
}
PieD subst(SubstV substFn) {
return sbustFn.forTop(t, r);
}
}
class Bot extends PieD {
Object t;
PieD r;
Bot(Object _t, PieD _r) {
t = _t;
r = _r;
}
PieD rem(RemV remFn) {
return remFn.forBot();
}
PieD subst(SubstV substFn) {
return sbustFn.forBot();
}
}
|
我们可以给 RemV 和 SubstV 这两个类也抽象出一个类型出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | abstract class PieVisitorD {
abstract PieD forBot();
abstract PieD forTop(Object t, PieD r);
}
interface PieVisitorI {
PieD forBot();
PieD forTop(Object t, PieD r);
}
class RemV implements PieVisitorI {
Object o;
RemV(Object _o) {
o = _o;
}
public PieD forBot() {
return new Bot();
}
public PieD forTop(Object t, PieD r) {
if (o.equals(t))
return r.accept(this);
else
return new Top(t, r.accept(this));
}
}
class SbustV implements PieVisitorI {
Object n;
Object o;
SubstV(Object _n, Object _o) {
n = _n;
o = _o;
}
public PieD forBot() {
return new Bot();
}
public PieD fotTop(Object t, PieD r) {
if (o.equals(t))
return new Top(n, r.accept(this));
else
return new Top(t, r.accept(this));
}
}
|
同步修改 PieD
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | abstract class PieD {
abstract PieD accept(PieVisitorI ask);
}
class Bot extends PieD {
PieD accept(PieVisitorI ask) {
return ask.forBot();
}
}
class Top extends PieD {
Object t;
PieD r;
Top(Object _t, PieD _r) {
t = _t;
r = _r;
}
PieD accept(PieVisitorI ask) {
return ask.forTop(t, r);
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | class LtdSubstV implements PieVisitorI {
int c;
Object n;
Object o;
LtdSubstV(int _c, Object _n, Object _o) {
c = _c;
n = _n;
o = _o;
}
public PieD forBot() {
return new Bot();
}
public PieD forTop(Object t, PieD r) {
if (c == 0)
return new Top(t, r);
else
if (o.equals(t))
return new Top(n, r.accept(LtdSubstV(c-1, n, o)));
else
return new Top(t, r.accept(this));
}
}
|
第六条建议
当一个自引用的访问者类的参数发生改变时,别忘记重新创建一个新的访问者类实例。
comments powered by Disqus