Visitor模式示例程序:
https://github.com/ConfuseCat/DesignPattern/tree/master/src/AccessDataStructure/Visitor
Visitor模式原理
在Visitor模式中,数据结构与处理被分离开来。编写一个表示“访问者”的类来访问数据结构中的元素,并把对各元素的处理来交给访问者类,这样,当需要增加新的处理时,我们只需要编写新的访问者,然后让数据结构可以接受访问者的访问即可。
Visitor模式的类图
Visitor模式中的角色
- Visitor(访问者)
Visitor角色负责对数据结构中每个具体的元素(ConcreteElement角色)声明一个用于访问XXXX的visit(XXXX)方法。visit(XXXX)是用于处理(XXXX)的方法,负责实现该方法的是ConcreteVisitor角色。 - ConcreteVisitor(具体的访问者)
ConcreteVisitor角色负责实现Visitor角色所决定的接口。它要实现所有的visit(XXXX)方法,既实现如何处理每个ConcreteElement角色。 - Element(元素)
Element角色表示Visitor角色的访问对象。声明了接受访问者的accept方法。accept收到的参数是Visitor角色。 - ConcreteElement(具体的元素)
ConcreteElement角色负责实现Element角色所定义的接口。 - ObjectStructure(对象结构)
ObjectStructure角色负责处理Element角色的集合,ConcreteVisitor角色为每个Element角色都准备了处理方法
Visitor模式中的调用关系
element.accept(visitor)
visitor.visit(element)
ConcreteElement和ConcreteVisitor这两个角色共同决定了实际进行的处理,这种消息分发的方式一般被称为双重分发(double dispatch)
Visitor模式的特点
- 易于增加ConcreteVisitor角色
使用Visitor模式可以很容易地增加ConcreteVisitor角色。因为具体的处理被交给ConcreteVisitor角色负责,因此完全不用修改ConcreteElement。 - 难以增加ConcreteElement角色
新增ConcreteElement角色时,需要在Visitor中新增visit方法,并在所有的Visitor子类中实现这个方法
工作条件
在Visitor模式中,对数据结构中的元素进行处理的任务被分离出来,交给Visitor类负责。要达到这个目的Element角色必须向Visitor角色公开足够多的信息。
访问者只有从数据结构中获取了足够多的信息后才能工作。如果无法获取到这些信息,他就无法工作。这样做的缺点是,如果公开了不应当被公开的信息将来对数据结构的改良会变得非常困难。