锁定老帖子 主题:Visitor - 访问者模式
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-08
最后修改:2008-12-08
wangdi 写道 引用 当然,Visitor也有它自身的限制。它不适合于业务数量的经常变化,因为一旦新增或删除一些Service时,需要对visitor进行相应的增删。也就是说具体Service与Visitor是耦合的。 其实,我非常想知道关于visitor模式的定义,,有了准确定义,实现应该会比较简单。
注:我这儿的accept()、process()方法和lz的对应的方法是不一样的。。 public interface IVisitor { public void accept(IService service); } public interface IService { public void process(IVisitor vistor); } public class Fund implements IService { public void process(IVisitor vistor){ System.out.println("处理" + this); } public String toString(){ return "基金业务"; } } public class Saving implements IService { public void process(IVisitor vistor) { System.out.println("处理" + this); } public String toString() { return "存款业务"; } } public class Visitor implements IVisitor { public void accept(IService service) { service.process(this); } } public class VisitorClients0 { public static void main(String[] args) { IVisitor visitor = new Visitor(); IService fundService = new Fund(); IService savingService = new Saving(); visitor.accept(fundService); visitor.accept(savingService); } } 网上关于访问者大多数定义都像楼主所举的。 但是访问者模式,重点是 不改变原有的类与类继承关系上,为原有的类体系增加新的功能 这是类图.由于163的也是一个减化图,因此自已重新传一张,进行说明 上图中ObjectStructure所指示的 类结构,是固定的,是不希望发生变化的。但是,这个类的各个子类,他们要经常增加新的功能或操作。如何不改变这个类结构,又能在原有的基础上增加新的操作呢? 则这些子类ConcreateElenmentA、ConcreateElenmentB 预先调用一个功能扩展方法(即accept).如果没有功能变化,这个对象就是null,或有他是其方法中的是一个空语句。 而这个功能扩展方法,有一个参数-------Vistor对象, 这个对象装载着新功能变化。Vistor类的方法,对应着Element中各个子类,使用了accept方法的方法,如果当Element中的某个子类如ConcreateElenmentA,要增加功能了,则把新功能写在Vistor子类中.具体作法是,单写一个类,让它继承Vistor,由于这里是增加ConcreateElenmentA的功能,则在自已写的这个类中覆盖VistorConcreateElenmenA方法就行了。然后把自已写的类,生成一个实例,传递给ConcreateElenmentA对象. 简单说: 1 Element 类继承体系中,其继承关系不变,各个子类不变。但是,各个子类的却经常需要增加新功能。 -----------这是我们的想要达到的目的。 2 实现方法: 先定义一套方法封装在vistor类中。这套方法中,每个方法对应着一个Element子类。Element子类则在事先在代码中,谳用这个vistor对象中与自已相对应的方法。而accept方法,就是传输管道。 当用户要增加 Element的子类ConcreateElenmentA时,具体使用如下: (1) 写一个 Vistor1继承Vistor。 Vistor1中,覆盖VistorConcreateElenmenA方法,写新加入的功能。 (2)生成Vistor1的实例。其名取为vistor1 (3)生成ConcreateElenmentA的实例,取名 concreateElenmentA (4)定义一个 Element变量,名为e,其值为vistor1 ; 定义一个Vistor变量,名为v,其值为concreateElenmentA (5) 用如下语句增加ConcreateElenmentA的实例的功能。 e.accpt(v) (6) 当ConcreateElenmentA的实例的功能又变化了,则 修改第一条与第四条。重写一个Vistor的子类,并赋值给变量v即可。 其他代码根本不用改变了。出色的达到了我们想要的目的. 3 这个场景可用spring的AOP 4 题化话------ 访问者名字的由来。也许是Element的各个子类---------为来访的客人预留下了座位。来访客人每次带一大包实用的礼物,让Element的子类的实例增加自已的魔法功能。来访的客人各不相同,带来的礼物五花八门,于是Element的子类的实例,展现出魔术般的神奇效果。 ====================================================== 以上是三年前对 vitor的个人理解。尘封了N久的记忆,总算被打开了。说事在的,二十三种模式,仅有少数几种留下了深刻的印像,其余的都淡忘掉了。唯独模式设计的封装变化点在心中。好在,还有自已能看懂的笔记一直保存着。 |
|
返回顶楼 | |