|
1
11
在GoF书中定义访问者模式的主要原因是,C++没有任何形式的运行时类型标识(RTTI)。他们使用“双重分派”让目标对象告诉他们他们的类型。一个相当酷,但难以形容的把戏。 您所描述的和GoF访问者模式(正如您所提到的)的主要区别在于,您有一个显式的“dispatch”方法——“visit”方法,它检查参数的类型并将其发送到显式的visitFoo、visitBar等方法。
把这一切放在一个地方,基本的GoF模式看起来像(我是一个Java人,所以请原谅Java代码而不是这里的C)
(请注意,如果您愿意,此接口可以是具有默认方法实现的基类) 以及你的数据对象 需要实现“接受”方法:
注意:这与您在GoF版本中提到的最大区别是,我们可以使用方法重载,以便“visit”方法名保持一致。这使得每个数据对象都有一个相同的“accept”实现,减少了出错的机会
然后,您可以根据自己的需要实现Visitor接口。 请注意,在相同或不同的包中添加新类型(例如Type4)所需的更改比您描述的要少。如果在同一个包中,我们将向Visitor接口(以及每个实现)添加一个方法,但是您不需要“dispatch”方法。
顺便说一句,我在约翰霍普金斯大学教设计模式,我想推荐的是一种非常动态的方法。 从一个简单的单对象访问者界面开始:
然后创建一个VisitorRegistry
你会像这样用这个
您还可以在运行时重新注册(和取消注册)不同的访问者组合,甚至可以从一些配置信息加载要执行的操作的定义。 希望这有帮助! |
|
|
2
3
看看
acyclic visitor pattern
. 它还提供了您在访客适应中列出的优点,而不是
真正的访问者可以选择他们访问的子类:
它是“非循环的”,因为它在层次结构中的类型和访问者中的方法之间没有循环依赖关系。 |
|
|
3
2
你建议对访问者进行子类化,在某些访问者中只处理类的子集,这会使情况更糟。现在,当开发人员创建CypItEngEnter的新子类时,他们将需要对现有的所有访问者类进行密切的了解,以便知道哪些访问者类和哪些类不需要更改,这将很容易出错。 |
|
4
1
一些语言也有一些限制,使得这一点非常不吸引人。Java除了通过接口之外没有多个继承。要求每个复合元素和访问者从同一个基类派生将形成一个粗略的类型层次结构。 i、 你的方法不允许访问者和CompositeElement成为接口。 |
|
|
5
0
我不喜欢visitA、visitB、visitWhatever、acceptation、acceptB、acceptWhatever的实现,因为这种方法意味着每次向层次结构添加类时都会破坏接口。 请看一下 an article I've written about this . 本文使用真实的例子详细地解释了这一切,包括一个不破坏任何接口的多态案例。 |