访问者模式(Visitor Pattern)

一、概念

访问者模式(Vistor Pattern)是用于数据结构与数据操作分离的一种设计模式。是指封装一些作用于某种数据结构中的各种元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新操作。

  • 模式动机:对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式也有所不同
  • 核心思想:将数据结构与数据操作(访问者角色)分离。使得对元素的操作具备优秀的扩展性,我们可以通过扩展不同的数据操作类型(访问者角色)实现对相同元素的不同操作。

二、适用场景

  1. 数据结构稳定,但是作用于数据结构上的操作经常变化
  2. 需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景。

三、参与者

  • 抽象访问者角色(AbstractVisitor):接口或者抽象类。声明了一个或者多个具体访问者角色必须实现的方法
    • 定义对具体元素的visit方法,参数就是具体元素,理论上来说方法数等于元素个数
    • 访问者模式适用于元素结构比较稳定的场景。 如果元素不稳定经常变化的话,那么访问者是要一直修改的,不适合使用访问者模式。
  • 具体访问者(ConcreteVistor):实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个具体访问元素操作。如示例中的CustomerAVisitor
  • 抽象元素角色(AbstractElement):接口或者抽象类。声明一个接受方法,接收一个访问者对象作为一个参数 。
  • 具体元素(ConcreteElement):实现了抽象元素角色所规定的接受操作。
    • 提供接受访问者访问的具体实现,通常都是采用visitor.visit()来实现 
  • 结构对象角色(ObjectStruture):用来维护元素,并提供一个方法来接受访问者访问所有的元素
  • Client 用户

四、代码例子

在小镇上有一个医院和一个餐厅,每天都会有不同的人访问这两个地方,由于访问者不同到这两个地方要做的事也有区别。医生去医院是为了工作给病人看病,厨师去医院是为了检查身体,医生去餐厅是为了吃饭,厨师去餐厅是为了工作给客人烹饪菜肴。

抽象访问者角色(AbstractVisitor):AbstractVisitor

具体访问者(ConcreteVistor):Doctor、Chef

抽象元素角色(AbstractElement):AbstractElement

具体元素(ConcreteElement):Hospital、Resteraunt

五、UML图

 

六、优缺点

(一)优点

  1. 解耦了数据结构和数据操作,使得操作集合可以独立变化。
  2. 访问者角色非常易于扩展。
    • 可以在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能;
  3. 每种角色各司其职,符合单一职责原则。
    • 通过访问者将无关的行为分离,,使职责单一

(二)缺点

  1. 增加元素类型困难,如果元素类型变化就需要修改访问者角色代码,违反了开闭原则,也不利于维护。
    • 对象结构变化困难,若对象结构发生了改变,访问者的接口和访问者的实现也都要发生相应的改变;
  2. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
    • 比如我们示例中的访问者接口,定义的方法依赖的是具体元素而不是抽象元素
  3. 违反了迪米特原则,因为具体元素对访问者公布细节;
posted @ 2022-12-15 08:51  ImreW  阅读(53)  评论(0编辑  收藏  举报