我们需要扩展生成的行为与现有的对象模型并不一致,或者不修改层次结构中的类,就无法扩展层次结构的行为,这时可以使用访问者模式为对这个层次结构进行扩展提供支持。访问者模式的目的在于不改变一个层次结构中的类的情况下,我们可以为一个层次结构定义定义一个新的操作,扩展过程中无需访问原有的代码。
目的为了表示一个作用于某个对象结构中的各元素的操作,可以在不改变各元素的类的前提下定义作用于这些元素的新操作.(GOF)
使用访问者模式,必须定义两个类层次结构,一个对应于接受操作的元素类,另一个对应于定义对元素的操作的访问者类。给访问者类层次增加一个新的子类即可以创建一个新的操作。为所有类都增加一个Accept操作;创建一个接口,所有操作均被该接口定义。访问者模式不要求层次结构的所有类都实现一个Accept()方法,但是如果某个类实现了Accept()方法,那么这个为会作为Visitor()方法的一个参数,而Accept()方法由访问者的接口定义。
适用性:
1 .一个对象结构内部包含很多实现了不同接口的类对象,你想对这些对象执行依赖于其具体类的操作。
2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。访问者模式使得你可以将相关的操作集中起来定义在一个类中,当该对象结构被很多应用共享时,用访问者模式让每个应用仅包含需要用到的操作。
3.定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
参与者:
1. 抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体访问者角色必须实现的接口。 具体为该对象结构中的ConcreteElement的每一个类声明一个Visit操作,该操作的名字和特征标示了发送Visit请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。这样访问这就可以通过该元素的特定接口直接访问它。
2. 具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。 具体为实现每个由Visitor声明的操作,每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储他的局部状态。这一个状态常常在遍历该结构的过程中累积信息。
3.抽象元素(Element)角色: 声明一个Accept操作,该操作接受一个访问者对象作为参数。
4. 具体元素(ConcreteElement)角色:实现抽象元素角色所规定的Accept操作。
5. 结构对象(ObiectStructure)角色:提供一个方法可以遍历结构中的所有元素,或者可以设计成一个复合对象或者一个聚集。
访问者模式是一个有争议的模式,因为可能在设计过程中陷入过程流中的无限循环,也可能为层次结构中加入危险的依赖关系,当层次关系结构发生变化时,会导致这种依赖无效.与其他设计模式一样,该模式也不是一种必须使用的模式,通常可以找到一种更可靠的模式作为其替代方案,除非别无选择.
示例代码:



































































































[1] http://tianli.blog.51cto.com/190322/45702
[2] http://www.cnblogs.com/singlepine/archive/2005/10/30/265025.html