17

Open/Closed Principleを尊重してVisitor パターンを実装することは可能ですが、新しい訪問可能なクラスを追加することはできますか?

オープン/クローズの原則では、「ソフトウェア エンティティ (クラス、モジュール、関数など) は、拡張に対してオープンである必要がありますが、変更に対してクローズされている必要があります」と述べています。

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 Principle を尊重します。AbstractVisitable クラス ツリーは、拡張できないため、Open/Closed Principle を尊重しません。

以下のように 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);
   }
};
4

2 に答える 2

8

C ++では、Acyclic Visitor(pdf)が必要なものを提供します。

于 2008-10-05T10:55:34.323 に答える
4

「表現の問題」に関する調査を確認することをお勧めします。例を参照してください。

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

問題は主に学術的なものだと思いますが、それは多くの研究がなされてきたものなので、既存の言語やさまざまな言語拡張機能で実装するさまざまな方法について読むことができるものが少しあります。

于 2008-10-05T09:52:36.960 に答える