1
3
两件事:
|
2
7
有很大的不同。 访问者模式使用接口,但其目的是能够对一个或多个类(实现接口的类)执行操作,而不必更改类。因此,实现实际上“访问”类并在不修改类的情况下执行它的操作。 接口是一个基本概念,用于为可能不同的类组提供通用的API。接口的典型测试是共享接口的类在至少一个方面(is-like-a)是相似的,在这些情况下可以这样对待。 Here is a simple example on wikipedia that shows a couple of visitors in java. |
3
4
这些示例中最重要的区别是,在访问者案例中,您保留了编译时具体类型的“this”。这允许您使用双调度,其中要调用的方法依赖于具体的数据类型和访问者实现。双调度只是多调度的一种特殊情况,其中调用的方法依赖于接收者和方法参数的类型。Java当然是单调度的,但是其他一些语言支持多分派。 访问者模式背后的基本驱动力是,通过在具体节点上使用接口,需要添加到复合数据结构中的每个操作都必须更改每个节点。访问者模式在节点上使用通用(静态)模式,这样动态添加操作就很容易了。缺点是修改数据结构(通过添加或删除具体节点)变得更加困难,因为所有操作访问者都受到影响。 一般来说,这种权衡比较好,因为在数据结构上扩展操作比更改数据结构本身更频繁。下面是我关于如何使用访问者的一篇较长的文章和一些注意事项: 您可能会问,是否有一个模式允许我们同时执行这两种操作:添加操作或扩展数据结构,而不破坏现有代码。这就是菲利普·韦德勒创造的表达问题。您可以在此找到一些链接以及更多内容: |
4
1
当您有一个由许多不同类组成的数据结构,并且您有多个算法需要对每个类执行不同的操作时,就会使用访问者模式。在您的示例中,doInterface实现只对一个类型执行一个操作。您唯一要做的就是打印get()的结果,因为您将o强制转换为t,所以只能对t类型的类执行此操作。 如果你想将你的接口应用到一个典型的访问者风格的类中,你的dointerface.perform函数的类可能会以一个大的if-else if语句结束,如下所示:
因为它使用对象,所以它将允许具有任何类型的调用方创建只能在运行时显示的错误。访问者通过为数据结构中的每种类型创建一个“visittype”函数来绕过这个问题。然后,数据结构中的类负责知道访问者要调用的函数。映射是由每个数据结构的类执行的,这些类实现一个accept函数,然后调用visitor类。如果访问者上不存在该类型的函数,则会出现编译错误。accept方法如下:
访问者模式的一个问题是,在一个样本中,要真正做到这一点需要大量的代码。我认为这就是为什么很多人不理解它,因为它很容易被其他代码分散注意力。我创建了一个简单的文件系统示例,希望能够更清楚地显示如何使用访问者。它创建一个包含一些文件和目录的组合,然后在层次结构上执行两个操作。实际上,您可能需要两个以上的数据类和两个以上的操作来证明此模式的合理性,但这只是一个示例。
|
5
0
我看到的唯一一件显而易见的事情是,通过存储接口,您必须执行两个操作,而不是一个操作来调用它。我认为,如果在设置接口后重复执行相同的操作,这是有意义的,但是我认为您可以坚持使用标准的访问者并完成相同的事情。 |
Alex Pander · cleaner代码的嵌套命名空间[已关闭] 6 年前 |
Jamil Noyda · 导入模块的最佳方式Python[复制] 6 年前 |
Samselvaprabu · 我们是否需要不惜任何代价避免重复? 6 年前 |
user9549524 · 基于一列的值从二维矩阵中提取值 6 年前 |
MedAl · 不使用try/catch处理异常 6 年前 |
Declan McKenna · 特殊情况模式在Swift中是否多余? 6 年前 |