目      的:封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

定      义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作

优      点:

        1. 访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。

       2. 访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。

       3. 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。

       4. 积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点

缺      点:

       1. 增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。

       2. 破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的

应用场景:

           1:数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。

           2:被访问的类结构非常稳定的情况下使用。系统很少出现需要加入新节点的情况。如果出现需要加入新节点的情况,那么就必须在每一个访问对象里加入一个对应于这个新节点的访问操作,而这是对一个系统的大规模修改,因而是违背"开一闭"原则的。

应用案例:

             先来看看UML图如下:

设计模式利剑19--访问者模式_工作

         Visitor:抽象访问者,抽象类或者接口,声明访问者可以访问那些元素,具体到程序中就是visit方法的参数定义那些对象是可以被访问

             ConcreteVisitor:具体访问者,它影响访问者访问到一个类后该怎么干,要做什么事情

             Element:抽象元素,接口或者抽象类,声明接受那一类访问者访问,程序上是通过Accept中的参数来决定

             ObjectStruture:结构对象,一般容纳在多个不同类,不同接口的容器,如ArrayList

             先来看一个例子,要打印所有员工的工作信息,员工包括管理人员与普通员工,实现UML图如下:

设计模式利剑19--访问者模式_uml_02