oop - 访客模式的替代方案?

标签 oop design-patterns visitor-pattern

我正在寻找访客模式的替代方案。让我只关注该模式的几个相关方面,同时跳过不重要的细节。我将使用形状示例(抱歉!):

  1. 您有一个实现 IShape 接口(interface)的对象层次结构
  2. 您有许多要对层次结构中的所有对象执行的全局操作,例如绘制、WriteToXml 等...
  3. 很容易直接投入到 IShape 接口(interface)中添加 Draw() 和 WriteToXml() 方法。这不一定是一件好事 - 每当您希望添加要在所有形状上执行的新操作时,必须更改每个 IShape 派生类
  4. 为每个操作实现一个访问者,即 Draw 访问者或 WirteToXml 访问者,将该操作的所有代码封装在一个类中。添加新操作只需创建一个新的访问者类,该类对所有类型的 IShape 执行该操作
  5. 当您需要添加新的 IShape 派生类时,本质上会遇到与 3 中相同的问题 - 必须更改所有访问者类以添加一个方法来处理新的 IShape 派生类型

您读到的有关访问者模式的大多数地方都指出,第 5 点几乎是该模式发挥作用的主要标准,我完全同意。如果 IShape 派生类的数量是固定的,那么这可能是一种非常优雅的方法。

因此,问题是当添加新的 IShape 派生类时 - 每个访问者实现都需要添加一个新方法来处理该类。这充其量是令人不快的,往坏了说是不可能的,并且表明这种模式并不是真正设计来应对此类变化的。

那么,问题是有人遇到过处理这种情况的替代方法吗?

最佳答案

您可能想看看 Strategy pattern 。这仍然可以让您分离关注点,同时仍然能够添加新功能,而无需更改层次结构中的每个类。

class AbstractShape
{
    IXmlWriter _xmlWriter = null;
    IShapeDrawer _shapeDrawer = null;

    public AbstractShape(IXmlWriter xmlWriter, 
                IShapeDrawer drawer)
    {
        _xmlWriter = xmlWriter;
        _shapeDrawer = drawer;
    }

    //...
    public void WriteToXml(IStream stream)
    {
        _xmlWriter.Write(this, stream);

    }

    public void Draw()
    {
        _drawer.Draw(this);
    }

    // any operation could easily be injected and executed 
    // on this object at run-time
    public void Execute(IGeneralStrategy generalOperation)
    {
        generalOperation.Execute(this);
    }
}

更多信息位于相关讨论中:

Should an object write itself out to a file, or should another object act on it to perform I/O?

关于oop - 访客模式的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/985960/

相关文章:

oop - 什么是控制反转?

java - 设计一个抽象类,以便任何人都可以扩展它并以多态方式使用扩展类

java - 设计模式多功能到一功能到多功能的实现

c++ - boost::apply_visitor 不是 [some] 类的成员

c# - 将对象转换为正确的类型

java - 将 Map 的 Map 更改为泛型类型

c++ - 将基类对象分配给派生类

java - 什么是核心 Java 中的桥接模式示例?

c++ - 寻求更好地理解 std::visit

Java多线程可伸缩性问题