简介
在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新操作。
主要解决:稳定的数据结构和易变的操作耦合问题
优点:1、符合单一职责原则;2、具有很好的扩展性
缺点:1、具体元素对访问者公布细节,违反了迪米特原则;2、违反了依赖倒置原则,依赖具体类而没有依赖抽象
使用场景:
- 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作
- 需要对一个对象结构中的对象进行很多不同的且不相关的操作,而需要避免让这些操作”污染”这些对象的类,也不希望在增加新操作时修改这些类。
访问者模式成员:
- Visitor(抽象访问者):抽象访问者为对象结构中每一个具体元素类ConcreteElement声明一个访问操作,从这个操作的名称或参数类型可以清楚知道需要访问的具体元素的类型,具体访问者则需要实现这些操作方法,定义对这些元素的访问操作。
- ConcreteVisitor(具体访问者):具体访问者实现了抽象访问者声明的方法,每一个操作作用于访问对象结构中一种类型的元素。
- Element(抽象元素):一般是一个抽象类或接口,定义一个Accept方法,该方法通常以一个抽象访问者作为参数。
- ConcreteElement(具体元素):具体元素实现了Accept方法,在Accept方法中调用访问者的访问方法以便完成一个元素的操作。
- ObjectStructure(对象结构):对象结构是一个元素的集合,用于存放元素对象,且提供便利其内部元素的方法。
示例
创建一个定义接受操作的 ComputerPart 接口(抽象元素)。Keyboard、Mouse、Monitor(各个元素) 和 Computer(元素集合)是实现了 ComputerPart 接口的实体类。我们将定义另一个接口 ComputerPartVisitor,它定义了访问者类的操作。Computer 使用实体访问者来执行相应的动作。
抽象元素
1 | public interface ComputerPart { |
抽象元素的存在是为了让所有具体元素都具有接收访问者的方法。
具体元素
1 | public class Keyboard implements ComputerPart { |
抽象访问者
1 | public interface ComputerPartVisitor { |
抽象访问者为每一种元素都声明了一个访问操作,将元素作为参数来重载访问操作方法。通过实现不同的访问操作,就可以对不同元素进行不同的访问了
访问者实现类
1 | public class ComputerPartDisplayVisitor implements ComputerPartVisitor { |
对抽象访问者的各个具体的访问方法进行实现
测试
1 | public class VisitorPatternDemo { |
上述程序流程为:
- main方法中创建元素集合类:Computer,它同时也是一个元素类。
- 创建一个访问者对象:ComputerPartDisplayVistor;并使用 Computer类接收访问者对象的方法accept接收此访问者对象
- 来到了Computer类的接收方法内,能够发现,Computer类有多个元素组成的元素数组,accept方法中遍历元素数组,将Computer类接收到的访问者对象,同样用于访问这些元素。
- 每一个元素接收到访问者对象后,在元素的accept方法中,调用了访问者对象的visit方法,并将元素对象引用传给visit方法,这样,同一个访问者对象的visit方法就可以根据传入参数的不同调用多个重载方法中的某一个方法了。
- 在元素数组中所有元素都处理完访问对象后,Computer类才开始处理访问对象
也就是说程序实现了通过一个访问者对象,访问了多个元素,并且可以看到,当访问对象改变时,访问结果也会发生变化。
参考
- 本文作者: xczll
- 本文链接: https://xczllgit.github.io/2020/03/30/designPattern/2020-03-30-visitorPattern/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!