访问者模式与开放/关闭原则:如何添加新的可访问对象?

Posted

技术标签:

【中文标题】访问者模式与开放/关闭原则:如何添加新的可访问对象?【英文标题】:Visitor-Pattern vs. open/closed principle: how to add new visitable object? 【发布时间】:2013-08-03 17:03:58 【问题描述】:

我正在研究访问者模式,我想知道这种模式与开放/封闭原则有何关系。我在几个网站上读到“这是遵循开放/封闭原则的一种方式。”(引自wikipedia)。

在another website 上,我了解到它遵循开放/封闭原则,这样可以很容易地向您的程序添加新访问者,以便“在不更改现有代码的情况下扩展现有功能 ”。同一个网站提到这种访问者模式有一个主要缺点:“如果将新的可访问对象添加到框架结构中,则所有实现的访问者都需要修改。”使用 Java 的反射框架。

现在,这个解决方案是不是有点像 hack 解决方案?我的意思是,我也在其他一些博客上找到了这个解决方案,但代码看起来更像是一种解决方法!

对于向访问者模式的现有实现添加新可访问对象的问题,是否有另一种解决方案?

【问题讨论】:

【参考方案1】:

Visitor 是所有模式中最繁琐的模式之一,并且具有您提到的不可扩展性方面的缺点。将双重分派引入单分派语言本身就是一种草率的解决方法。当你考虑到它的所有缺点时,诉诸反思并不是一个可怕的选择。

事实上,反射在任何情况下都不是一个非常糟糕的选择:考虑一下今天的代码有多少是用动态语言编写的,换句话说,什么都不使用反射,并且应用程序不会失败因为它而分开。

类型安全当然有其优点,但是当您发现自己遇到了静态类型和单一调度的障碍时,请毫不后悔地拥抱反射。另请注意,通过正确缓存 Method 对象,反射方法调用几乎与静态调用一样快。

【讨论】:

【参考方案2】:

这完全取决于访问者应该完成什么工作,但在大多数情况下,这就是interfaces 的用途。考虑SortedSet;实现需要能够比较集合中的不同对象以了解它们的顺序,但它不需要了解有关对象的任何其他内容。解决方案(按自然顺序排序)是使用Comparable 接口。

【讨论】:

以上是关于访问者模式与开放/关闭原则:如何添加新的可访问对象?的主要内容,如果未能解决你的问题,请参考以下文章

访问者模式,visitor

JavaScript 设计模式的七大原则(未完成)

设计模式软件设计七大原则 ( 开闭原则 )

如何使用反射满足工厂模式中的开闭原则?

设计模式之单一职责原则

设计模式 - 七大设计原则