訪問者パターン+オープン/クローズド原則
-
05-07-2019 - |
質問
Open / Closed Principleでは、「ソフトウェアエンティティ(クラス、モジュール、関数など)は拡張のために開かれ、修正のために閉じられるべきだ」と述べています。
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);
}
};
解決
C ++では、非周期的ビジター(pdf)が取得されますあなたが欲しいもの。
他のヒント
「式の問題」に関する調査を確認することをお勧めします。例:
http://lambda-the-ultimate.org/node/2232
問題の大部分は学術的なものであると思いますが、これは多くの研究が行われているものであるため、既存の言語またはさまざまな言語拡張でそれを実装するさまざまな方法について読むことができるものが少しあります。