Skip to content

Latest commit

 

History

History

visitor

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

访问者 Visitor

✨模式类型✨✨ ✨✨难度✨ ✨ ✨✨实用性✨✨ ✨✨重要程度✨✨ ✨✨经典性✨✨ ✨✨历史性✨
行为型模式 ★★★ ⬇️ ★★★ ⬆️ ★★★ ⬆️ 💚 ⬆️ 💚 ⬆️

概念

在访问者模式(Visitor Pattern)中,使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

用途

主要将数据结构与数据操作分离,解决稳定的数据结构和易变的操作耦合问题。

模式架构

访问者模式是一种将数据操作与数据结构分离的设计模式。

参与角色对象

  • Visitor:访问者接口或者抽象类,它定义了对每一个元素(Element访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素个数(Element的实现类个数)是一样的。访问者模式要求元素的类族要稳定,如果经常添加、移除元素类,必然会导致频繁地修改Visitor接口,如果这样则不适合使用访问者模式。从这点不难看出,访问者模式要求元素类的个数不能经常改变(就是说,如果元素类的个数经常改变,则说明不适合使用访问者模式)。
  • ConcreteVisitor:具体的访问者,它需要给出对每一个元素类访问时所产生的具体行为。
  • Element: 元素接口或者抽象类,它定义了一个接受访问者accept)的方法,其意义是指每一个元素都要可以被访问者访问
  • ConcreteElement:具体的元素类,它提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法
  • ObjectStructure:定义当中所提到的对象结构,对象结构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特性的类,它会含有一组元素(Element),并且可以迭代这些元素,供访问者访问

UML关系图

1546674847984

优点与缺点

  • 优点

    • 符合单一职责原则。
    • 优秀的扩展性
    • 灵活性
  • 缺点

    • 具体元素对访问者公布细节,违反了迪米特原则。
    • 具体元素变更比较困难
    • 违反了依赖倒置原则依赖了具体类,没有依赖抽象。

代码实现

访问者模式的实现要点如下:

  • 定义Visitor访问者接口或者抽象类,在接口中定义好访问对应Element元素接口或者抽象类的方法接口。
  • 实现或继承Visitor访问者接口或者抽象类,实现接口中的方法,可以通过接收到的具体Element元素接口或者抽象类完成一部分业务。
  • 定义Element角色接口对象,定义一个accept的方法接收Visitor访问者接口。
  • 定义具体的Element角色接口实现类,完成accept的方法实现。在具体的Element角色接口实现类中完成通过Visitor调用对应的visitXxx的方法。

示例参考

应用场景

访问者模式适用于:

  • 数据结构稳定,作用于数据结构的操作经常变化的时候。对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类
  • 当一个数据结构中,一些元素类需要负责与其不相关的操作的时候,为了将这些操作分离出去,以减少这些元素类的职责时,可以使用访问者模式。
  • 有时在对数据结构上的元素进行操作的时候,需要区分具体的类型,这时使用访问者模式可以针对不同的类型,在访问者类中定义不同的操作,从而去除掉类型判断

应用实例参考

JavaSDK

GoSDK

PythonSDK

JavaScript Libs

总结

  • 在访问者模式中,使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。
  • 主要解决:将数据结构与数据操作分离,解决稳定的数据结构和易变的操作耦合问题。
  • 访问者模式的优点有:符合单一职责原则;优秀的扩展性;灵活性。
  • 访问者模式适用于:数据结构稳定,作用于数据结构的操作经常变化的时候;需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类;当一个数据结构中,一些元素类需要负责与其不相关的操作的时候,为了将这些操作分离出去,以减少这些元素类的职责时,可以使用访问者模式;有时在对数据结构上的元素进行操作的时候,需要区分具体的类型,这时使用访问者模式可以针对不同的类型,在访问者类中定义不同的操作,从而去除掉类型判断