访问者模式 + 开闭原则

17

是否有可能实现访问者模式,遵守开闭原则,但仍能够添加新的可访问类?

开闭原则指出:“软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。”

struct ConcreteVisitable1;
struct ConcreteVisitable2;

struct AbstractVisitor
{
   virtual void visit(ConcreteVisitable1& concrete1) = 0;
   virtual void visit(ConcreteVisitable2& concrete2) = 0;
};

struct AbstractVisitable
{
   virtual void accept(AbstractVisitor& visitor) = 0;
};

struct ConcreteVisitable1 : AbstractVisitable
{
   virtual void accept(AbstractVisitor& visitor)
   {
      visitor.visit(*this);
   }
};

struct ConcreteVisitable2 : AbstractVisitable
{
   virtual void accept(AbstractVisitor& visitor)
   {
      visitor.visit(*this);
   }
};

你可以实现任意数量的从AbstractVisitor派生的类:它是开放的,可以扩展。你不能添加一个新的可访问类,因为从AbstractVisitor派生的类将无法编译:它是关闭的,不能修改。
AbstractVisitor类树遵循开闭原则。 AbstractVisitable类树不遵循开闭原则,因为它无法扩展。
除了如下扩展AbstractVisitor和AbstractVisitable之外,还有其他解决方案吗?
struct ConcreteVisitable3;

struct AbstractVisitor2 : AbstractVisitor
{
   virtual void visit(ConcreteVisitable3& concrete3) = 0;
};

struct AbstractVisitable2 : AbstractVisitable
{
   virtual void accept(AbstractVisitor2& visitor) = 0;
};

struct ConcreteVisitable3 : AbstractVisitable2
{
   virtual void accept(AbstractVisitor2& visitor)
   {
      visitor.visit(*this);
   }
};
2个回答

8

另请参见:http://butunclebob.com/ArticleS.UncleBob.VisitorVersusInstanceOf,该文章比较了三种替代方案。 - jaco0646

4

您可能想查看与“表达式问题”相关的研究,例如:

http://lambda-the-ultimate.org/node/2232

我认为这个问题大多是学术性的,但它是被广泛研究的一个问题,因此您可以阅读一些关于如何在现有语言中实现它或使用各种语言扩展的不同方法的资料。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接