您何时决定为您的对象使用访问者?

我一直认为一个对象需要数据和消息来对它采取行动。你什么时候想要一个对对象有外在性的方法?您遵循什么经验法则来访者?这是假设您可以完全控制对象图。


答案 1

当将操作应用于相当复杂的数据结构的所有元素时,访问者模式特别有用,对于这些元素,遍历是非平凡的(例如,并行遍历元素,或遍历高度互连的数据结构)或实现双重调度。如果要按顺序处理元素,并且不需要双重调度,那么实现自定义的迭代器和迭代器通常是更好的选择,特别是因为它更适合其他API。


答案 2

我一直认为一个对象需要数据和消息来对它采取行动。你什么时候想要一个对对象有外在性的方法?您遵循什么经验法则来访者?这是假设您可以完全控制对象图。

有时,在一个类中定义特定对象的所有行为并不方便。例如,在Java中,如果你的模块需要一个方法在另一个模块中最初定义的一堆类中实现,这很复杂,因为你不能在原始类文件以外的其他地方编写,这意味着你不能在不改变现有源代码的情况下扩展系统(在Smalltalk或其他语言中,你可以将方法分组到不绑定到特定文件的扩展名中)。toXmltoXml

更一般地说,在静态类型语言中,(1)向现有数据类型添加新函数的能力与(2)添加支持相同函数的新数据类型实现之间存在紧张关系 - 这被称为表达式问题维基百科页面)。

面向对象的语言在第 2 点表现出色。如果您有接口,则可以安全轻松地添加新的实现。函数式语言在第 1 点表现出色。它们依赖于模式匹配/临时多态性/重载,因此您可以轻松地向现有类型添加新函数。

访客模式是在面向对象设计中支持第1点的一种方式:您可以以类型安全的方式轻松地使用新行为扩展系统(如果您进行手动模式匹配,则不会出现这种情况,因为如果没有涵盖案例,该语言永远不会警告您)。if-else-instanceof

当有一组固定的已知类型时,通常会使用访问者,我认为这就是你所说的“完全控制对象图”的意思。示例包括解析器中的令牌、具有各种类型节点的树以及类似情况。

因此,总而言之,我会说你的分析是正确的:)

PS:访客模式与复合模式配合得很好,但它们也单独使用


推荐