| 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 | abstract class FruitD {} // 水果 
class Peach extends FruitD {  // 桃 
    public boolean equals(Object o) {
        return (o instanceof Peach);
    }
}
class Apple extends FruitD { // 苹果 
    public boolean equals(Object o) {
        return (o instanceof Apple);
    }
}
class Pear extends FruitD { // 梨 
    public boolean equals(Object o) {
        return (o instanceof Pear);
    }
}
class Lemon extends FruitD { // 柠檬 
    public boolean equals(Object o) {
        return (o instanceof Lemon);
    }
}
class Fig extends FruitD { // 无花果 
    public boolean equals(Object o) {
        return (o instanceof Fig);
    }
}
 | 
| 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 44 45 46 47 48 49 50 51 52 53 | abstract class TreeD {
    abstract boolean accept(bTreeVisitorI ask);
    abstract int accept(iTreeVisitorI ask);
    abstract TreeD accept(tTreeVisitorI ask);
}
class Bud extends TreeD {
    boolean accept(bTreeVisitorI ask) {
        return ask.forBud();
    }
    int accept(iTreeVisitorI ask) {
        return ask.forBud();
    }
    TreeD accept(tTreeVisitorI ask) {
        return ask.forBud();
    }
}
class Flat extends TreeD {
    FruitD f;
    TreeD t;
    Flat(FruitD _f, TreeD _t) {
        f = _f;
        t = _t;
    }
    boolean accept(bTreeVisitorI ask) {
        return ask.forFlat(f, t);
    }
    int accept(iTreeVisitorI ask) {
        return ask.forFlat(f, t);
    }
    TreeD accept(tTreeVisitorI ask) {
        return ask.forFlat(f, t);
    }
}
class Split extends TreeD {
    TreeD l;
    TreeD r;
    Split(Treed _l, TreeD _r) {
        l = _l;
        r = _r;
    }
    boolean accept(bTreeVisitorI ask) {
        return ask.forSplit(l, r);
    }
    int accept(iTreeVisitorI ask) {
        return ask.forSplit(l, r);
    }
    TreeD accept(tTreeVisitorI ask) {
        return ask.forFlat(l, r);
    }
}
 | 
| 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 | interface bTreeVisitorI {
    boolean forBud();
    boolean forFlat(FruitD f, TreeD t);
    boolean forSplit(TreeD l, TreeD r);
}
class bIsFlatV implements bTreeVisitorI {
    public boolean forBud() {
        return true;
    }
    public boolean forFlat(FruitD f, TreeD t) {
        return t.accept(this);
    }
    public boolean forSplit(TreeD l, TreeD r) {
        return false;
    }
}
class bIsSplitV implements bTreeVisitorI {
    public boolean forBud() {
        return true;
    }
    public boolean forFlat(FruitD f, TreeD t) {
        return false;
    }
    public boolean forSplit(TreeD l, TreeD r) {
        return l.accept(this) && r.accept(this);
    }
}
class bHasFruitV implements bTreeVisitorI {
    public boolean forBud() {
        return false;
    }
    public boolean forFlat(FruitD f, TreeD t) {
        return true;
    }
    public boolean forSplit(TreeD l, TreeD r) {
        return l.accept(this) || r.accept(this);
    }
}
 | 
| 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 | interface iTreeVisitorI {
    int forBud();
    int forFlat(FruitD f, TreeD t);
    int forSplit(TreeD l, TreeD r);
}
class iHeightV implements iTreeVisitorI {
    public int forBud() {
        return 0;
    }
    public int forFlat(FruitD f, TreeD t) {
        return t.accept(this) + 1;
    }
    public int forSplit(TreeD l, TreeD r) {
        return (l.accept(this) |_| r.accept(this)) + 1;
    }
}
class iOccursV implements iTreeVisitorI {
    FruitD a;
    iOccursV(FruitD _a) {
        a = _a;
    }
    public int forBud() {
        return 0;
    }
    public int forFlat(FruitD f, TreeD t) {
        if (f.equals(a))
            return t.accept(this) + 1;
        else
            return t.accept(this);
    }
    public int forSplit(TreeD l, TreeD r) {
        return l.accept(this) + r.accept(this);
    }
}
 | 
| 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 | interface tTreeVisitorI {
    TreeD forBud();
    TreeD forFlat(FruitD f, TreeD t);
    TreeD forSplit(TreeD l, TreeD r);
}
class tSubstV implements tTreeVisitorI {
    FruitD n;
    FruitD o;
    tSubstV(FruitD _n, FruitD _o) {
        n = _n;
        o = _o;
    }
    public TreeD forBud() {
        return new Bud();
    }
    public TreeD forFlat(FruitD f, TreeD t) {
        if (o.equals(f))
            return new Flat(n, t.accept(this));
        else
            return new Flat(f, t.accept(this));
    }
    public TreeD forSplit(TreeD l, TreeD r) {
        return new Split(l.accept(this), r.accept(this));
    }
}
 | 
上面的三个接口是不是有点繁琐?那么将它合并起来。
| 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | interface TreeVisitorI {
    Object forBud();
    Object forFlat(FruitD f, TreeD t);
    Object forSplit(TreeD l, TreeD r);
}
abstract class TreeD {
    abstract Object accept(TreeVisitorI ask);
}
class Bud extends TreeD {
    Object accept(TreeVisitorI ask) {
        return ask.forBud();
    }
}
class Flat extends TreeD {
    FruitD f;
    TreeD t;
    Flat(FruitD _f, TreeD _t) {
        f = _f;
        t = _t;
    }
    Object accept(TreeVisitorI ask) {
        return ask.forFlat(f, t);
    }
}
class Split extends TreeD {
    TreeD l;
    TreeD r;
    Split(Treed _l, TreeD _r) {
        l = _l;
        r = _r;
    }
    Object accept(TreeVisitorI ask) {
        return ask.forSplit(l, r);
    }
}
class IsFlatV implements TreeVisitorI {
    public Object forBud() {
        return new Boolean(true);
    }
    public Object forFlat(FruitD f, TreeD t) {
        return t.accept(this);
    }
    public Object forSplit(TreeD l, TreeD r) {
        return new Boolean(false);
    }
}
class bIsSplitV implements bTreeVisitorI {
    public boolean forBud() {
        return new Boolean(true);
    }
    public boolean forFlat(FruitD f, TreeD t) {
        return new Boolean(false);
    }
    public boolean forSplit(TreeD l, TreeD r) {
        if (((Boolean)(l.accept(this))).booleanValue())
            return r.accept(this);
        else:
            return new Boolean(false);
    }
}
 | 
第七条建议
当为多个不同的类型设计访问者协议时,使用 Object 来创建一个统一的协议。
最后再来罗嗦到不行的。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class OccursV implements TreeVisitorI {
    FruitD a;
    iOccursV(FruitD _a) {
        a = _a;
    }
    public Object forBud() {
        return new Integer(0);
    }
    public Object forFlat(FruitD f, TreeD t) {
        if (f.equals(a))
            return new Integer(((Integer)(t.accept(this))).intValue() + 1);
        else
            return t.accept(this);
    }
    public int forSplit(TreeD l, TreeD r) {
        return new Integer(((Integer)(l.accept(this))).intValue()
                           +
                           ((Integer)(r.accept(this))).intValue());
    }
}
 | 
                    
comments powered by Disqus