访问者模式-好人打贱人

来源:互联网 发布:新西兰网络无信号 编辑:程序博客网 时间:2024/06/02 15:01

接  3.5 访问者模式(5.11) 

访问者模式的核心是解决a.foo(b)的双分派问题。所以还是给出一个简单的例子。好人打贱人。好人有南拳、北腿类,贱人有鬼子、棒子、B2等。

访问者模式中客户Test会创建各种各样的对象,只调用一个方法 ”好人"的 打(贱人 j) 方法。


/** *  * @author yqj2065 * @version 2014.9 */public abstract class 好人{    //测试目标 好人 .打(贱人),应该能够找到2*3个方法体    public abstract void 打(贱人 j);        abstract void 打JP();    abstract void 打Bar();    abstract void 打B2();}abstract class 贱人{    public abstract void cmd(好人 x);// Command}

按照采用的技术不同,好人中可以使用重载(程序中就需要用instanceof)、可以使用不同方法名(本例采用的方式)——这些方法由贱人们调用,Test不需要知道,所以采用默认访问控制

关键点:不同于GoF,Visitor为客户提供了一个统一的访问接口 打(贱人 j) 

贱人之所以贱,在GoF中它的方法名不是command而是accept。这个方法的目的是将重载的打(贱人 j) 方法区分开来,转换成 x.打JP()等。

import static tool.Print.*;public class 南拳 extends 好人{    @Override public void 打(贱人 j){        j.cmd(this);    }    @Override void 打JP(){  pln("南拳.打JP()"); }    @Override void 打Bar(){ pln("南拳.打Bar()");}    @Override void 打B2(){  pln("南拳.打B2()"); }}class JP extends 贱人{    @Override public void cmd(好人 x){//命令        x.打JP();    }}//其他的北腿、棒子、B2 略
测试:

    public static void test访问者(){        好人 m1 = (好人)God.create("3-30-q");//南拳对象        好人 m2 = (好人)God.create("3-30-t");//北腿对象        贱人 a = (贱人)God.create("3-30-jp");        贱人 b = (贱人)God.create("3-30-bar");        贱人 c = (贱人)God.create("3-30-b2");        // x .打(y);        m1.打(a);        m1.打(b);        m1.打(c);        m2.打(a);        m2.打(b);        m2.打(c);    }
输出:
南拳.打JP()
南拳.打Bar()
南拳.打B2()
北腿.打JP()
北腿.打Bar()
北腿.打B2()

现在,好人中增加刀客类,按照南拳的样子写一个。测试代码创建一个刀客对象m3,m3.打(a);m3.打(b);m3.打(c);

输出:

南拳.打JP()....
北腿.打B2()
刀客.打JP()
刀客.打Bar()
刀客.打B2()

与抽象工厂类似,增加一个好人的子类很方便;增加一个贱人的子类,好人的类层次都需要修改。


如果愿意,也可以用一个ArrayList把贱人对象放进去,把贱人叫作Element,JP是具体的元素...

这就是访问者模式的基本结构。


1 0
原创粉丝点击