動機
需要の変化によるビルドへのソフトウェアのプロセスでは、クラス階層の一部は、多くの場合、そうすることが基本クラス内で直接変更した場合、新しい動作(メソッド)を追加する必要があり、それは非常に重いサブクラスをもたらしますでも、オリジナルのデザインを破壊し、負担を変更。
どのようにクラス階層内の各クラスの実行時にクラス階層の前提を変更することなく、動的に上記の問題を避けるために、透過的に新しい操作を追加しますか?
パターン定義
オブジェクト構造の効果の各要素の動作を表します。(拡張)クラスの前提に作用するこれらの要素の文字(変化)の動作の各要素の(安定性)を変更しないように定義することができる
構造
に高レベルのインターフェイスを提供しながら、その要素を列挙する:ObjectStructure(オブジェクト構造)これは、訪問者がその要素にアクセスすることができます。
例
class Visitor;
class Element
{
public:
virtual void accept(Visitor& visitor) = 0; //第一次多态辨析
virtual ~Element(){}
};
class ElementA : public Element
{
public:
void accept(Visitor &visitor) override {
visitor.visitElementA(*this);
}
};
class ElementB : public Element
{
public:
void accept(Visitor &visitor) override {
visitor.visitElementB(*this); //第二次多态辨析
}
};
class Visitor{
public:
virtual void visitElementA(ElementA& element) = 0;
virtual void visitElementB(ElementB& element) = 0;
virtual ~Visitor(){}
};
//==================================
//扩展1
class Visitor1 : public Visitor{
public:
void visitElementA(ElementA& element) override{
cout << "Visitor1 is processing ElementA" << endl;
}
void visitElementB(ElementB& element) override{
cout << "Visitor1 is processing ElementB" << endl;
}
};
//扩展2
class Visitor2 : public Visitor{
public:
void visitElementA(ElementA& element) override{
cout << "Visitor2 is processing ElementA" << endl;
}
void visitElementB(ElementB& element) override{
cout << "Visitor2 is processing ElementB" << endl;
}
};
int main()
{
Visitor2 visitor;
ElementB elementB;
elementB.accept(visitor);// double dispatch
ElementA elementA;
elementA.accept(visitor);
return 0;
}
検索と変更パッケージ:デザインパターンが多いと言います。ビジターパターンを採用するかどうか、「変更」に依存しています。Visitorパターンは、「変化」オブジェクト構造に続いて、特定の訪問者ですが、特定の要素が変更された場合、あなたはそれが「全体としての状況に影響を与える」ため、ビジターパターンを使用することはできません
ので、Visitorパターンの最大の欠点それは、(新しい要素サブクラスを追加)クラス階層を拡張Vistorクラスへの変更をもたらすことがあります。従ってVistorモードが安定した要素クラス階層に適しており、動作は、しばしば頻繁な変化に直面しています。