访问者模式(Visitor Pattern)
一、概念
访问者模式(Vistor Pattern)是用于数据结构与数据操作分离的一种设计模式。是指封装一些作用于某种数据结构中的各种元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新操作。
- 模式动机:对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式也有所不同。
- 核心思想:
将数据结构与数据操作(访问者角色)分离
。使得对元素的操作具备优秀的扩展性,我们可以通过扩展不同的数据操作类型(访问者角色)实现对相同元素的不同操作。
二、适用场景
数据结构稳定
,但是作用于数据结构上的操作经常变化
- 需要对
不同数据类型(元素)
进行操作,而不使用分支判断具体类型
的场景。
三、参与者
- 抽象访问者角色(AbstractVisitor):接口或者抽象类。声明了一个或者多个具体访问者角色必须实现的方法
- 定义对具体元素的visit方法,参数就是具体元素,理论上来说方法数等于元素个数
访问者模式适用于元素结构比较稳定的场景
。 如果元素不稳定经常变化的话,那么访问者是要一直修改的,不适合使用访问者模式。
- 具体访问者(ConcreteVistor):实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个具体访问元素操作。
如示例中的CustomerAVisitor
。 - 抽象元素角色(AbstractElement):接口或者抽象类。声明一个接受方法,
接收一个访问者对象作为一个参数
。 - 具体元素(ConcreteElement):实现了抽象元素角色所规定的接受操作。
- 提供接受访问者访问的具体实现,通常都是采用
visitor.visit()
来实现
- 提供接受访问者访问的具体实现,通常都是采用
- 结构对象角色(ObjectStruture):用来维护元素,并提供一个方法来接受访问者访问所有的元素
- Client 用户
四、代码例子
在小镇上有一个医院和一个餐厅,每天都会有不同的人访问这两个地方,由于访问者不同到这两个地方要做的事也有区别。医生去医院是为了工作给病人看病,厨师去医院是为了检查身体,医生去餐厅是为了吃饭,厨师去餐厅是为了工作给客人烹饪菜肴。
抽象访问者角色(AbstractVisitor):AbstractVisitor
具体访问者(ConcreteVistor):Doctor、Chef
抽象元素角色(AbstractElement):AbstractElement
具体元素(ConcreteElement):Hospital、Resteraunt
五、UML图
六、优缺点
(一)优点
解耦了数据结构和数据操作
,使得操作集合可以独立变化。- 访问者角色非常易于扩展。
- 可以在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能;
- 每种角色各司其职,符合单一职责原则。
- 通过访问者将无关的行为分离,,使职责单一
(二)缺点
- 增加元素类型困难,
如果元素类型变化就需要修改访问者角色代码
,违反了开闭原则,也不利于维护。- 对象结构变化困难,若对象结构发生了改变,访问者的接口和访问者的实现也都要发生相应的改变;
- 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
- 比如我们示例中的访问者接口,
定义的方法依赖的是具体元素而不是抽象元素
。
- 比如我们示例中的访问者接口,
- 违反了迪米特原则,因为具体元素对访问者公布细节;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了