访问者模式与双分派

Java中模拟双分派  作为命令模式的应用,得到了一个有用的结构。从该结构出发唾手可得访问者模式。

再次说明,yqj2065不关心访问者模式的“对象结构”。

双分派中的结构,如图所示。

如果一个类OverloadUnit定义了foo(Z1)、 foo(Z2)方法,Z作为命令角色定义handleFoo()帮助它完成双分派。当我们想看见a.foo(b)这一完整的双分派演示,原先的OverloadUnit修改为X类层次。此时,命令的执行者不再是固定的OverloadUnit,所以,Z需要一个注入方法

package method.command.doubleDispatch2;
public abstract class Z  {
    public abstract void setX(X receiver);
    public abstract void say();
    public abstract void walk();
    public abstract void handleFoo();// Command
}
子类

package method.command.doubleDispatch2;
import static tool.Print.*;
public class Z1 extends Z {
    private X receiver;
    @Override public void say(){        pln(" Z1.say()");    }
    @Override public void walk(){       pln(" Z1.walk()");   }
    @Override public void setX(X receiver){
        this.receiver = receiver;
    }
    @Override public void handleFoo(){//命令
        receiver.foo(this);
    }
}//Z2 略
定义了foo(Z1)、 foo(Z2)方法的X类层次
package method.command.doubleDispatch2;
public abstract class X{ //OverloadUnit
    //测试目标 x .foo(z),应该能够找到4个方法体
    public abstract void foo(Z z);
    abstract void foo(Z1 z);
    abstract void foo(Z2 z);
}
package method.command.doubleDispatch2;
import static tool.Print.*;
/**
 * @author yqj2065
 * @version 0.1
 */
public class X1 extends X{
    @Override public  void foo(Z z){
        z.setX(this);
        z.handleFoo();
    }; 

    @Override void foo(Z2 z){
        p("X1.foo(Z2)-");
        z.say();
    }
    @Override void foo(Z1 z){
        p("X1.foo(Z1)-");
        z.say();//
    }
}
测试代码

    public static void ab(){
        Z z1 = (Z)God.create("3-22-Z1");//Z1对象
        Z z2 = (Z)God.create("3-22-Z2");//Z2对象
        X a = (X)God.create("3-22-X1");
        X b = (X)God.create("3-22-X2");
        // x .foo(z);
        a.foo(z1);
        a.foo(z2);
        b.foo(z1);
        b.foo(z2);
    }
输出:
X1.foo(Z1)- Z1.say()
X1.foo(Z2)- Z2.say()
X2.foo(Z1)- Z1.walk()
X2.foo(Z2)- Z2.walk()

这个代码完整地演示了双分派。但是,你将没有含义的foo改为visit,能不能有所感想。

你可以定义X3,其中
    @Override void foo(Z1 z){
        p("X1.foo(Z1)-");
        newMothed();//名义上是Z的新方法,其实...
    }

这就是访问者模式。




你可能感兴趣的:(访问者模式与双分派)