type
status
date
slug
summary
tags
category
icon
password
整理定义
中文定义:访问者模式
英文定义:visitor pattern
出处 | 定义 |
中国大百科全书 | 描述一个对象结构中某个对象元素需要执行的操作一种设计模式,使用该设计模式可以在不改变操作元素的类的前提下定义作用于这些元素的新操作 |
设计模式 | 访问者模式是一种行为设计模式, 它能将算法与其所作用的对象隔离开来。 |
百度百科 | 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。 |
维基百科 | 访问者模式是一种将算法与对象结构分开的软件设计模式。 由于这种分离,可以将新操作添加到现有对象结构中,而无需修改结构。 它是面向对象编程和软件工程中遵循开放/封闭原则的一种方法。 |
复述展开
What is visitor pattern?
访问者模式是一种行为设计模式,它允许你在不改变类的情况下增加新的操作。这种模式主要包含访问者(Visitor)和元素(Element)两种角色。元素接口定义了一个
accept
方法,该方法通常以一个访问者作为参数;访问者接口则定义了一组访问方法,用于处理不同类型的元素。访问者模式的主要思想是将数据结构和数据操作分离。数据结构负责存储数据,而数据操作则由访问者来完成。这样,当我们需要增加新的操作时,只需要增加新的访问者,而无需修改数据结构。
🌰*1
文档编辑器:在一个文档编辑器中,文档可以包含多种元素,如文本、图片、表格等。如果我们想要实现一些操作,如渲染、打印、检查拼写等,可以使用访问者模式。每种操作可以定义为一个访问者,元素则提供一个
accept
方法,用于接受访问者的访问。🌰*2
编译器:在编译器中,源代码可以被解析为一个抽象语法树(AST)。如果我们想要实现一些操作,如类型检查、代码生成、优化等,可以使用访问者模式。每种操作可以定义为一个访问者,AST节点则提供一个
accept
方法,用于接受访问者的访问。🌰*3
电商平台:在一个电商平台中,可以有多种商品,如书籍、电子产品、服装等。如果我们想要实现一些操作,如打折、计算运费、生成描述等,可以使用访问者模式。每种操作可以定义为一个访问者,商品则提供一个
accept
方法,用于接受访问者的访问。访问者模式结构
- 访问者 (Visitor) 接口声明了一系列以对象结构的具体元素为参数的访问者方法。 如果编程语言支持重载, 这些方法的名称可以是相同的, 但是其参数一定是不同的。
- 具体访问者 (Concrete Visitor) 会为不同的具体元素类实现相同行为的几个不同版本。
- 元素 (Element) 接口声明了一个方法来 “接收” 访问者。 该方法必须有一个参数被声明为访问者接口类型。
- 具体元素 (Concrete Element) 必须实现接收方法。 该方法的目的是根据当前元素类将其调用重定向到相应访问者的方法。 请注意, 即使元素基类实现了该方法, 所有子类都必须对其进行重写并调用访问者对象中的合适方法。
- 客户端 (Client) 通常会作为集合或其他复杂对象 (例如一个组合树) 的代表。 客户端通常不知晓所有的具体元素类, 因为它们会通过抽象接口与集合中的对象进行交互。
优缺点
优点:
- 开闭原则。 你可以引入在不同类对象上执行的新行为, 且无需对这些类做出修改。
- 单一职责原则。 可将同一行为的不同版本移到同一个类中。
- 访问者对象可以在与各种对象交互时收集一些有用的信息。 当你想要遍历一些复杂的对象结构 (例如对象树), 并在结构中的每个对象上应用访问者时, 这些信息可能会有所帮助。
缺点:
- 每次在元素层次结构中添加或移除一个类时, 你都要更新所有的访问者。
- 在访问者同某个元素进行交互时, 它们可能没有访问元素私有成员变量和方法的必要权限。
理解体会
我们可以看出,访问者模式是一种非常强大的设计模式,它可以让我们的代码更加灵活,更易于扩展和维护。然而,我们也需要注意它的缺点,即增加新的数据结构比较困难。因此,在使用访问者模式时,我们需要根据实际情况来权衡。
快速跳转链接
【概念解析】启动
【概念解析】Day 1 - 10
【概念解析】Day 11 - 20
【概念解析】Day 21 - 30
【概念解析】Day 31 - 40
【概念解析】Day 41 - 50
【概念解析】Day 51 - 60
【概念解析】Day 61 - 70
【概念解析】Day 71 - 80
【概念解析】Day 81 - 90
- 作者:eachenkuang
- 链接:https://kuangyichen.com/article/industry-day49
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。