January Star
  • Home
  • Categories
  • Tags
  • Archives

Boring Protocols

哈哈, 之前 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
comments powered by Disqus

Published

Sep 25, 2014

Category

java

Tags

  • java 13
  • oop 13

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor