c++ - 访问者模式与具有输入类型限制的向下转型

标签 c++ architecture visitor-pattern

对于特定类型的对象,我有不同的访问者。我在实现可用于所有类型的通用接口(interface)时遇到问题。在这种情况下使用的最佳架构是什么?我想出了 3 种不同的解决方案,但它们对我来说看起来都很丑陋:(为了简单起见,删除了一些诸如虚拟析构函数之类的东西)

class IObject {
    virtual void Accept(IVisitor& visior) = 0;
};

class Text: IObject {
    void Accept(IVisitor& visitor) {
        visitor.Visit(*this);
    }
};

class Image: IObject {
    void Accept(IVisitor& visitor) {
        visitor.Visit(*this);
    }
};

class IVisitor {
    virtual void Visit(Text& text) = 0;
    virtual void Visit(Image& image) = 0;
};

class TextVisitor: IVisitor {
    void Visit(Text& text) {
        // Do some stuff with text
    }

    void Visit(Image& image) {
        // Image not supported, throw exception
    }
};

或者

class IObject {};
class Text: IObject {};
class Image: IObject {};

class IVisitor {
    virtual void Visit(IObject& object) = 0;
};

class TextVisitor: IVisitor {
    void Visit(IObject& object) {
        Text& text = dynamic_cast<Text&>(object);
        // Do some stuff with text
    }
};

或者

template <typename T>
class IVisitor {
    virtual void Visit(T& object) = 0;
};

class TextVisitor: IVisitor<Text> {
    void Visit(Text& text) {
        // Do some stuff
    }
};

class ImageVisitor: IVisitor<Image> {
    void Visit(Image& image) {
        // Do some stuff
    }
};

class ITextImagelVisitor: IVisitor<Text>, IVisitor<Image> {};

class VisitorDispatcher: ITextImageVisitor {
    void Visit(Text& text) {
        text_visitor_->Visit(text);
    }

    void Visit(Image& image) {
        image_visitor_->Visit(image);
    }

    std::shared_ptr<IVisitor<Text>> text_visitor_;
    std::shared_ptr<IVisitor<Image>> image_visitor_;
};

class IObject {
    virtual void Accept(ITextImageVisitor& visior) = 0;
};

class Text: IObject {
    void Accept(ITextImageVisitor& visitor) {
        visitor.Visit(*this);
    }
};

class Image: IObject {
    void Accept(ITextImageVisitor& visitor) {
        visitor.Visit(*this);
    }
};

最佳答案

答案显然取决于您在此想要实现的目标。 访问者模式用于处理组合对象,例如树并在该组合的子对象上调用自身。在您的示例中,这将是一个包含文本和图像的文本,其中包含文本和图像...这显然似乎没有多大意义,所以如果您实际上正在处理文本和图像,访问者可能不是您所需要的,您应该提供一些有关您想要实现的目标的更多信息。

到您的不同代码:

  1. 看起来不错,这是一个有效的访问者实现。访问者将处理任何不包含图像的合成。
  2. 看起来很糟糕,因为 dynamic_cast 。访问者模式的全部内容就是避免此类强制转换,并且该强制转换是不可扩展的。考虑例如对象层次结构中的更多类型,例如声音文件、视频等。使用dynamic_cast这里不会对你有太大帮助。如果您只想支持一种类型的对象,则不需要访问者。
  3. 看起来更糟。您的VisitorDispatcher 继承Visitor<Text>并且包含 Visitor<Text>以及。这充其量只是一个奇怪的设计。

关于c++ - 访问者模式与具有输入类型限制的向下转型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17165636/

相关文章:

python - 访客模式(从下到上)

c++ - 清理值而不向上或向下舍入

c++ - 使用 VS2015 更改应用程序的入口点

c++ - 在数组中查找唯一数字

.net - 两个应用程序之间的通信,SSIS 是可行的方法吗?

architecture - 以编程方式检测任何 html 页面上社交事件的名称、位置和开始时间

c# - 管理数据库中持久的动态网站设置

java - 将 List<Object> 分解为一组已知派生类型的列表

c++ - 二次方程 : negative discriminant in C++

C++ 访问者模式处理模板化字符串类型?