首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Visitor - 访问者方式

2012-10-27 
Visitor - 访问者模式话说有一个银行,有三个窗口,但是每个窗口的智能都是一样的,即都能办理所有的业务。因

Visitor - 访问者模式

话说有一个银行,有三个窗口,但是每个窗口的智能都是一样的,即都能办理所有的业务。因此每位来银行办理业务的人只要排队就是了,排到你了,就向业务员说明你要办理的业务,然后业务员根据你的业务选择不同的单据,打开不同的账本。……。

?

业务员此时典型的工作流程是:





 ,找不出真正实现者。感觉永远在自身调用自身。 




上图中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久的记忆,总算被打开了。说事在的,二十三种模式,仅有少数几种留下了深刻的印像,其余的都淡忘掉了。唯独模式设计的封装变化点在心中。好在,还有自已能看懂的笔记一直保存着。public class Client { public static void main(String[] args) { Service s1 = new Saving(); Service s2 = new Draw(); Service s3 = new Fund(); SavingVisitor sv= new SavingVisitor (); s1.accept(sv); DrawVisitor dv= new DrawVisitor (); s2.accept(dv); FundVisitor fv= new FundVisitor (); s3.accept(fv); } }
33 楼 yunhaifeiwu 2012-08-21   补充:

public class Service { 
    public void accept(Visitor visitor) { 
        visitor.process(this);   
    } 
}  

这个也必须要变。

热点排行