ホームページ >バックエンド開発 >C#.Net チュートリアル >C++ デザイン パターンにおける訪問者パターンの簡単な紹介

C++ デザイン パターンにおける訪問者パターンの簡単な紹介

黄舟
黄舟オリジナル
2017-01-17 13:24:241565ブラウズ

ビジター モード (ビジター): オブジェクト構造内の各要素に作用する操作を表し、各要素のクラスを変更せずにこれらの要素に作用する新しい操作を定義できます。

5 つのロール クラス:

Visitor: オブジェクト構造内の ConcreteElement の各クラスの Visit 操作を宣言します。

ConcreteVistor: ビジターによって宣言された各操作を実装する特定のビジター。各操作はアルゴリズムの一部を実装し、アルゴリズムのフラグメントは構造内のオブジェクトに対応するクラスです。

ELEment は、訪問者をパラメータとして受け取る Accept オペレーションを定義します。

ConcreteElement は、Accept 操作を実装する特定の要素です。

ObjectStructure は、その要素を列挙し、訪問者がその要素にアクセスできるようにする高レベルのインターフェイスを提供します。

適用可能な状況:

比較的安定したデータ構造を持つシステムに適用され、データ構造とデータ構造に作用する操作の間の結合が分離され、一連の操作が比較的自由に進化することが可能になります。

訪問者パターンの目的は、処理をデータ構造から分離することです。多くのシステムはアルゴリズムやデータ構造に応じて分離できますが、そのようなシステムが比較的安定したデータ構造と変更しやすいアルゴリズムを備えている場合は、ビジター モードを使用する方が適切です。ビジター モードの方が拡張が容易です。アルゴリズム操作の数。

利点:

訪問者モードの利点は、新しい操作を追加することが新しい訪問者を追加することを意味するため、新しい操作を簡単に追加できることです。訪問者パターンは、関連する動作を訪問者オブジェクトに集約します。

欠点:

新しいデータ構造を追加することが困難になります。

パターン実装:

[code]class ConcreteElementA;
class ConcreteElementB;

class Visitor
{
public:
     virtual void VisitConcreteElementA(ConcreteElementA *pElementA) = 0;
     virtual void VisitConcreteElementB(ConcreteElementB *pElementB) = 0;
};

class ConcreteVisitor1 : public Visitor
{
public:
     void VisitConcreteElementA(ConcreteElementA *pElementA);
     void VisitConcreteElementB(ConcreteElementB *pElementB);
};

void ConcreteVisitor1::VisitConcreteElementA(ConcreteElementA *pElementA)
{
     // 现在根据传进来的pElementA,可以对ConcreteElementA中的element进行操作
}

void ConcreteVisitor1::VisitConcreteElementB(ConcreteElementB *pElementB)
{
     // 现在根据传进来的pElementB,可以对ConcreteElementB中的element进行操作
}

class ConcreteVisitor2 : public Visitor
{
public:
     void VisitConcreteElementA(ConcreteElementA *pElementA);
     void VisitConcreteElementB(ConcreteElementB *pElementB);
};

void ConcreteVisitor2::VisitConcreteElementA(ConcreteElementA *pElementA)
{
     // ...
}

void ConcreteVisitor2::VisitConcreteElementB(ConcreteElementB *pElementB)
{
     // ...
}

// Element object
class Element
{
public:
     virtual void Accept(Visitor *pVisitor) = 0;
};

class ConcreteElementA : public Element
{
public:
     void Accept(Visitor *pVisitor);
};

void ConcreteElementA::Accept(Visitor *pVisitor)
{
     pVisitor->VisitConcreteElementA(this);
}

class ConcreteElementB : public Element
{
public:
     void Accept(Visitor *pVisitor);
};

void ConcreteElementB::Accept(Visitor *pVisitor)
{
     pVisitor->VisitConcreteElementB(this);
}

// ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素
class ObjectStructure
{
public:
     void Attach(Element *pElement);
     void Detach(Element *pElement);
     void Accept(Visitor *pVisitor);

private:
     vector<Element *> elements;
};

void ObjectStructure::Attach(Element *pElement)
{
     elements.push_back(pElement);
}

void ObjectStructure::Detach(Element *pElement)
{
     vector<Element *>::iterator it = find(elements.begin(), elements.end(), pElement);
     if (it != elements.end())
     {
          elements.erase(it);
     }
}

void ObjectStructure::Accept(Visitor *pVisitor)
{
     // 为每一个element设置visitor,进行对应的操作
     for (vector<Element *>::const_iterator it = elements.begin(); it != elements.end(); ++it)
     {
          (*it)->Accept(pVisitor);
     }
}

テストケース:

[code]int main()
{
     ObjectStructure *pObject = new ObjectStructure;

     ConcreteElementA *pElementA = new ConcreteElementA;
     ConcreteElementB *pElementB = new ConcreteElementB;

     pObject->Attach(pElementA);
     pObject->Attach(pElementB);

     ConcreteVisitor1 *pVisitor1 = new ConcreteVisitor1;
     ConcreteVisitor2 *pVisitor2 = new ConcreteVisitor2;

     pObject->Accept(pVisitor1);
     pObject->Accept(pVisitor2);

     if (pVisitor2) delete pVisitor2;
     if (pVisitor1) delete pVisitor1;
     if (pElementB) delete pElementB;
     if (pElementA) delete pElementA;
     if (pObject) delete pObject;

     return 0;
}

上記は、C++ デザイン パターンの訪問者パターンの簡単な紹介の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。