【发布时间】:2013-12-11 17:12:10
【问题描述】:
我阅读了很多关于访问者模式及其假定优势的文章。然而,对我来说,在实践中应用它们似乎并没有那么大的优势:
- “方便”和“优雅”似乎意味着大量的样板代码
- 因此,代码很难遵循。 'accept'/'visit' 也不是很具有描述性
- 如果您的编程语言没有方法重载(即 Vala),那么样板代码会更难看
- 您通常无法在不修改所有类的情况下将新操作添加到现有类型层次结构中,因为您需要新的“接受”/“访问”方法无处不在参数和/或返回值(到处更改类是这种设计模式应该避免的一件事!?)
- 向类型层次结构添加新类型需要更改所有 访问者。此外,您的访问者不能简单地忽略一个类型 - 您需要创建一个空的访问方法(再次样板)
这一切似乎都是一项艰巨的工作,而实际上你想做的只是:
// Pseudocode
int SomeOperation(ISomeAbstractThing obj) {
switch (type of obj) {
case Foo: // do Foo-specific stuff here
case Bar: // do Bar-specific stuff here
case Baz: // do Baz-specific stuff here
default: return 0; // do some sensible default if type unknown or if we don't care
}
}
我看到的唯一真正的优势(顺便说一句,我在任何地方都没有提到过):就 cpu 时间而言,访问者模式可能是实现上述代码 sn-p 的最快方法(如果你没有以上述伪代码的方式具有双重分派或高效类型比较的语言)。
问题:
- 那么,我错过了访问者模式的哪些优势?
- 可以使用哪些替代概念/数据结构来使上述虚构代码示例运行得同样快?
【问题讨论】:
-
IMO 你错过了一个重要的点......你应该永远(我会写得更大)有类似
switch (type of obj)的东西。不管是否访客。如果您的代码不是那样,那么您将不会编写任何样板代码。 -
示例访问者何时可以帮助您?想象一下编写一个实用程序来搜索文件内的文本。搜索引擎将访问每个文件系统项(文件将被访问,目录将访问传播到每个子项)。文件系统项目可以是目录、文件、指向 FTP 站点的链接……搜索引擎永远不会知道它的工作原理。访问者不应该知道确切的类型(不是因为访问者模式,而是因为 OOP 原则......)
-
访问者级别太低了。当您可以执行以下操作时,使用访问者毫无意义:cs.indiana.edu/~dyb/pubs/nano-jfp.pdf
-
@Adriano:您说访问者不应该知道确切的类型,但是当调用访问者的任何访问方法时,传递的参数就是确切的类型(IMO 这就是重点)。此外,如果您查看有关访问者模式的 Wikipedia 文章,您会发现 Scala 示例的工作方式与我的伪代码中所述完全一样。
-
@BillAskaga 这是一个示例和一个用例(此外,我会重载方法而不是那个,这也是关于 OOP 而不是访问者模式)。模式的重点始终是……您不必总是使用它们。当它们使您的代码变得更复杂时......不要使用它们。但是,再次,IMO 使该代码可读性降低的不是访问者,而是围绕它的基本逻辑。
标签: language-agnostic visitor-pattern