Шаблон посетителя + Открытый/Закрытый принцип

Возможно ли реализовать шаблон посетителя в отношении Open/Closed Принцип, но все же сможете добавлять новые классы для посещения?

Принцип Open/Closed гласит, что "объекты программного обеспечения (классы, модули, функции и т.д.) должны быть открыты для расширения, но закрыты для модификации".

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 соответствует принципу Open/Closed. Дерево классов AbstractVisitable не уважает принцип Open/Closed, поскольку он не может быть расширен.

Есть ли другое решение, чем расширить 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);
   }
};

Ответы

Ответ 1

В С++ Acyclic Visitor (pdf) получает то, что вы хотите.

Ответ 2

Возможно, вы захотите проверить исследование проблемы "выражения", например,

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

Я думаю, что проблема в основном академическая, но это то, что было изучено много, поэтому есть немного вещей, которые вы можете прочитать о различных способах реализации на существующих языках или с различными языковыми расширениями.