我正在寻找访客模式的替代方案。让我只关注模式的几个相关方面,而跳过不重要的细节。我将使用Shape的示例(对不起!):

  • 您具有实现IShape接口(interface)
  • 的对象层次结构
  • 您将对层次结构中的所有对象执行许多全局操作,例如绘图,WriteToXml等...
  • 诱人的是直接进入并将Draw()和WriteToXml()方法添加到IShape接口(interface)。这不一定是一件好事-每当您希望添加要在所有形状上执行的新操作时,都必须更改每个IShape派生的类
  • 为每个操作实现访问者,即Draw访问者或WirteToXml访问者将该操作的所有代码封装在一个类中。然后,添加新操作只需要创建一个新的访问者类,即可对所有类型的IShape
  • 执行该操作
  • 当您需要添加新的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);
        }
    }
    

    有关更多信息,请参见以下相关讨论:

    10-08 20:01