当前位置: 首页 > news >正文

访问者模式(Visitor Pattern)

🧠 访问者模式(Visitor Pattern)

访问者模式是一种行为型设计模式,它允许你在不改变对象结构的情况下,增加新的操作。简单来说,访问者模式可以使得你在不修改类的情况下,向已有的类中添加新的操作逻辑。

访问者模式的核心思想是:将数据结构与操作分离,把操作封装到访问者中。可以使得新增的操作可以通过访问者去执行,而无需修改数据结构本身。


🎯 为什么需要访问者模式?

  1. 扩展性强:访问者模式可以很容易地扩展新的操作,而不需要修改现有的数据结构或类。
  2. 双重分离:将操作和数据结构分离,允许数据结构和操作分开变化,符合“开闭原则”,易于维护和拓展。
  3. 封装行为:通过访问者模式封装多种操作,并避免修改原始类,减少类的复杂度。

优缺点分析

优点缺点
增加新的操作时不需要修改原有对象结构,符合开闭原则增加新的数据结构类时需要修改所有访问者,不利于数据结构的扩展
使得代码更符合“单一职责原则”,因为每个访问者只关心一种操作如果数据结构变化频繁,修改访问者可能成为负担
易于扩展新的操作而不影响原有代码复杂的系统中,访问者可能会增多,导致难以维护

🧩 Python 示例:图形绘制应用

假设有一个图形库,包含多个不同的形状:圆形矩形,我们希望能够对这些图形进行多个操作,例如计算面积、计算周长等。使用访问者模式可以实现动态增加新的操作,而不需要修改已有的图形类。

🎯 1️⃣ 图形接口(Shape)

from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef accept(self, visitor):pass
  • Shape 是所有图形的抽象类,定义了 accept() 方法,接受一个访问者对象来执行特定的操作。

🎯 2️⃣ 具体图形类(Concrete Shapes)

class Circle(Shape):def __init__(self, radius):self.radius = radiusdef accept(self, visitor):visitor.visit_circle(self)class Rectangle(Shape):def __init__(self, width, height):self.width = widthself.height = heightdef accept(self, visitor):visitor.visit_rectangle(self)
  • CircleRectangle 类是具体的图形类,分别代表圆形和矩形。
  • 每个图形类都实现了 accept() 方法,接受一个访问者,并将自身传递给访问者进行操作。

🎯 3️⃣ 访问者接口(Visitor)

class Visitor(ABC):@abstractmethoddef visit_circle(self, circle: Circle):pass@abstractmethoddef visit_rectangle(self, rectangle: Rectangle):pass
  • Visitor 类是一个抽象类,定义了每个图形类的访问方法。例如,visit_circle() 用于访问 Circle 对象,visit_rectangle() 用于访问 Rectangle 对象。

🎯 4️⃣ 具体访问者(Concrete Visitor)

class AreaVisitor(Visitor):def visit_circle(self, circle: Circle):# 计算圆形面积print(f"Area of Circle: {3.14 * circle.radius ** 2}")def visit_rectangle(self, rectangle: Rectangle):# 计算矩形面积print(f"Area of Rectangle: {rectangle.width * rectangle.height}")class PerimeterVisitor(Visitor):def visit_circle(self, circle: Circle):# 计算圆形周长print(f"Perimeter of Circle: {2 * 3.14 * circle.radius}")def visit_rectangle(self, rectangle: Rectangle):# 计算矩形周长print(f"Perimeter of Rectangle: {2 * (rectangle.width + rectangle.height)}")
  • AreaVisitorPerimeterVisitor 是具体的访问者类,分别用于计算图形的面积和周长。
  • 它们实现了 Visitor 接口的 visit_circle()visit_rectangle() 方法。

🎯 5️⃣ 客户端代码(执行操作)

# 创建图形
circle = Circle(5)
rectangle = Rectangle(4, 6)# 创建访问者
area_visitor = AreaVisitor()
perimeter_visitor = PerimeterVisitor()# 执行操作
circle.accept(area_visitor)  # 计算圆形的面积
circle.accept(perimeter_visitor)  # 计算圆形的周长rectangle.accept(area_visitor)  # 计算矩形的面积
rectangle.accept(perimeter_visitor)  # 计算矩形的周长
  • 我们创建了 CircleRectangle 两个图形对象。
  • 我们还创建了两个访问者:AreaVisitorPerimeterVisitor,用于计算图形的面积和周长。
  • 通过 accept() 方法,图形对象将自己传递给访问者,访问者执行相应的操作。

输出结果

Area of Circle: 78.5
Perimeter of Circle: 31.400000000000002
Area of Rectangle: 24
Perimeter of Rectangle: 20
  • AreaVisitor 计算了圆形和矩形的面积。
  • PerimeterVisitor 计算了圆形和矩形的周长。

🧭 类图(Mermaid)

接受
接受
«interface»
Shape
+accept(visitor: Visitor)
Circle
+accept(visitor: Visitor)
Rectangle
+accept(visitor: Visitor)
«interface»
Visitor
+visit_circle(circle: Circle)
+visit_rectangle(rectangle: Rectangle)
AreaVisitor
+visit_circle(circle: Circle)
+visit_rectangle(rectangle: Rectangle)
PerimeterVisitor
+visit_circle(circle: Circle)
+visit_rectangle(rectangle: Rectangle)

🧭 流程图(Mermaid)

User Circle Rectangle AreaVisitor PerimeterVisitor accept(AreaVisitor) visit_circle(Circle) "Area of Circle: 78.5" accept(PerimeterVisitor) visit_circle(Circle) "Perimeter of Circle: 31.4" accept(AreaVisitor) visit_rectangle(Rectangle) "Area of Rectangle: 24" accept(PerimeterVisitor) visit_rectangle(Rectangle) "Perimeter of Rectangle: 20" User Circle Rectangle AreaVisitor PerimeterVisitor

🧠 应用场景总结

场景示例
计算、处理复杂对象例如计算复合图形的面积和周长
扩展现有类的功能在不改变原始类的情况下添加新的操作
对象结构不常变化,但操作可能变化比如一个系统中对象结构不变,但可能需要动态改变操作行为

总结口诀

访问者模式
✅ 将操作封装到独立的访问者类中,避免修改原有类结构,符合开闭原则。
✅ 适用于需要在一个不常变化的对象结构上,动态增加新操作的场景。


如果你对访问者模式有其他问题或想了解更多细节,欢迎继续提问!

http://www.xdnf.cn/news/296155.html

相关文章:

  • STC单片机与淘晶驰串口屏通讯例程之03【单片机程序解析】
  • 名词解释DCDC
  • 位运算-详细总结
  • 人工智能浪潮中Python的核心作用与重要地位
  • 《人件》第四章 高效团队养成
  • 林业数智化转型初步设计方案
  • 网络原理(6)—— 应用层之HTTP协议
  • 广东省省考备考(第二天5.5)—申论作文
  • Baklib的数字化内容管理核心是什么?
  • 系统架构-层次式架构设计
  • 下载core5compat 模块时,被禁止,显示 - servese replied: Forbbidden. -->换镜像源
  • DeepSeek-提示词工程
  • 解密下一代AI:大模型技术的突破与挑战
  • 【Windows】Windows 使用bat脚本备份SVN仓库
  • AI融合SEO关键词优化
  • linux stm32mp157 GIC-V2 中断处理过程分析
  • 三角洲行动-高性能高品质的端手地形和生态技术文章解读
  • 2022年全国青少年信息素养大赛 Python编程挑战赛 小学/初中组 初赛真题答案详细解析
  • 为React组件库引入自动化测试:从零到完善的实践之路
  • 音视频作品:AI生成音乐、短视频的邻接权保护
  • 【day03】简写单词 | dd爱框框 | 除2!
  • AD创建元件符号
  • ERP系统源码,java版ERP管理系统源码,云端ERP
  • 【阿里云大模型高级工程师ACP习题集】2.9 大模型应用生产实践(下篇)
  • BC35 判断字母
  • 预训练到微调:深入理解AI的上下游任务
  • 网络延时 第四次CCF-CSP计算机软件能力认证
  • 41.寻找缺失的第一个正数:原地哈希算法详解
  • pyqt写一个单片机配置界面
  • DockerDesktop替换方案