Шаблон посетителя + Открытый / Закрытый Принцип - PullRequest
16 голосов
/ 05 октября 2008

Можно ли реализовать шаблон Visitor , соответствующий принципу 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);
   }
};

Ответы [ 2 ]

8 голосов
/ 05 октября 2008

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

4 голосов
/ 05 октября 2008

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

http://lambda -the-ultimate.org / узел / 2232

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

...