首页 > 代码库 > 《JAVA与模式》之访问者模式

《JAVA与模式》之访问者模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述访问者(Visitor)模式的:

  访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

 1 interface Service { 2  3     public void accept(Visitor visitor); 4 } 5  6 class Visitor { 7  8     public void process(Service service) { 9         // 基本业务10         System.out.println("基本业务");11     }12 13     public void process(Saving service) {14         // 存款15         System.out.println("存款");16     }17 18     public void process(Draw service) {19         // 提款20         System.out.println("提款");21     }22 23     public void process(Fund service) {24         System.out.println("基金");25         // 基金26     }27 28 }29 30 class Saving implements Service {31 32     public void accept(Visitor visitor) {33         visitor.process(this);34 35     }36 }37 38 class Draw implements Service {39 40     public void accept(Visitor visitor) {41         visitor.process(this);42 43     }44 }45 46 class Fund implements Service {47 48     public void accept(Visitor visitor) {49         visitor.process(this);50 51     }52 }

从上面例子可以看出,访问者借助的是java的动态分配机制,使得visitor可以顺利的执行相应对象的方法

 1 // 正常逻辑实现 2  3         Service service1 = new Saving(); 4         Service service2 = new Fund(); 5         Service service3 = new Draw(); 6         List<Service> ls = new ArrayList<Service>(); 7         ls.add(service1); 8         ls.add(service2); 9         ls.add(service3);10         for (Service service : ls) {11             if (service instanceof Saving) {12                 System.out.println("存款");13             } else if (service instanceof Fund) {14                 System.out.println("基金");15             } else if (service instanceof Draw) {16                 System.out.println("提款");17             }18         }19         //上述的问题是随着业务量增大 代码维护量会非常的大 需要不断的去判断 20         21         //采用访问者模式解决22         Service saving = new Saving();23         Service fund = new Fund();24         Service draw = new Draw();25         Visitor visitor = new Visitor();26         saving.accept(visitor);27         fund.accept(visitor);28         draw.accept(visitor);29         //上述中accept中实际上有观察者的影子 实际上 访问者我们也可以理解成一个对业务熟悉的观察者30         //他不断观察者是否有新的业务需求 有的话 进行相应的业务处理

小结:

采用Visitor的好处如上面说到的那样,当需要改变其中一项业务的处理时,不需要每个地方都进行修改,而只需要改动Visitor类中相应的处理函数就可以了。也就是说它适合于业务处理时常发生变动的情况。 

当然,Visitor也有它自身的限制。它不适合于业务数量的经常变化,因为一旦新增或删除一些Service时,需要对visitor进行相应的增删。也就是说具体Service与Visitor是耦合的

其实也是将责任抽象成一个个具体的类,从而避免在一个类中既处理逻辑又带有功能,违反了面向对象原则--责任单一

参考:

http://men4661273.iteye.com/blog/1635167

http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html