C++實現訪問者模式的基礎介紹
一、訪問者模式基礎知識
1.1 模式動機
對於系統中的某些對象中可能存在多種不同類型的元素,而且不同的調用者使用這些元素時也有所區別,這些調用者稱為訪問者。
訪問者模式(Visitor Pattern):表示一個作用於某對象結構中各元素的操作,它使我們可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
訪問者模式的應用場景:
- 訪問者模式適用於數據結構相對穩定的系統
- 它把數據結構和作用於數據結構之上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。
- 訪問者模式的目的是要把處理從數據結構分離出來。如果這樣的系統有比較穩定的數據結構,又有已與變化的算法的話,使用訪問者模式就是比較合適的,因為訪問者模式使得算法操作的增加變得更容易。反之亦然。
1.2 訪問者模式結構
訪問者模式中對象結構存儲瞭不同類型的元素對象,以提供不同訪問者訪問。訪問者模式包括兩個層次結構,一個是訪問者層次結構,提供瞭抽象訪問者和具體訪問者,一個是元素層次結構,提供瞭抽象元素和具體元素。
相同的訪問者可以以不同的方式訪問不同的元素,相同的元素可以接受不同訪問者以不同的方式訪問。
(1)Visitor (抽象訪問者)
抽象訪問者為對象結構類中每一個具體元素類聲明一個訪問操作。
(2)ConcreteVisitor (具體訪問者)
具體訪問者實現瞭每個由抽象訪問者聲明的操作,每一個操作用於訪問對象結構中一種元素類型的元素。
(3)Element(抽象元素)
抽象元素一般是抽象類或接口,定義一個accept()方法,該方法以一個抽象訪問者作為參數。
(4)ConcreteElement (具體元素)
具體訪問者實現瞭accept()方法,在其accept()
(5)ObjectStructure(對象結構)
對象結構是一個元素的集合,它用於存放元素對象,並且提供瞭遍歷其內部元素的方法。
1.3 訪問者模式優缺點
訪問者模式優點:
- 訪問者模式的優點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關的行為集中到一個訪問者對象中。
模式的缺點:
- 使增加新的元素類變得困難。在訪問者模式中,每增加一個新的元素都意味著要在抽象訪問者角色中增加一個新的抽象操作,並在每一個具體訪問者中增加相應的具體操作,違背“開閉原則”的要求。
1.4 訪問者模式應用
#include <iostream> #include <vector> using namespace std; 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){ // 現在根據傳進來的pElementA,可以對ConcreteElementA中的element進行操作 } void VisitConcreteElementB(ConcreteElementB *pElementB){ // 現在根據傳進來的pElementB,可以對ConcreteElementB中的element進行操作 } }; /*具體訪問者2*/ class ConcreteVisitor2 : public Visitor { public: void VisitConcreteElementA(ConcreteElementA *pElementA){ } void VisitConcreteElementB(ConcreteElementB *pElementB){ } }; /*抽象元素類 聲明accept()方法,用於接受訪問者的訪問*/ class Element { public: virtual void Accept(Visitor *pVisitor) = 0;//accept用於接受訪問者的訪問 }; /*具體元素類 通過調用Visitor類的visit()方法實現對元素的訪問*/ class ConcreteElementA : public Element { public: void Accept(Visitor *pVisitor)//通過調用visitor對象的 visit()方法實現對元素對象的訪問 { pVisitor->VisitConcreteElementA(this); } }; /*具體元素類 */ class ConcreteElementB : public Element { public: void Accept(Visitor *pVisitor) { pVisitor->VisitConcreteElementB(this); } }; // ObjectStructure類(對象結構類),能枚舉它的元素,可以提供一個高層的接口以允許訪問者訪問它的元素 class ObjectStructure { public: void Attach(Element *pElement){ elements.push_back(pElement); } void Detach(Element *pElement) { vector<Element *>::iterator it = find(elements.begin(), elements.end(), pElement); if (it != elements.end()) { elements.erase(it); } } void Accept(Visitor *pVisitor){ // 為每一個element設置visitor,進行對應的操作 for (vector<Element *>::const_iterator it = elements.begin(); it != elements.end(); ++it) { (*it)->Accept(pVisitor); } } 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; //調用accept方法 來接受訪問者對象的訪問 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; }
參考文獻:
【1】訪問者模式(c++實現):訪問者模式(c++實現)
【2】C++設計模式之訪問者模式: https://www.jb51.net/article/55999.htm
到此這篇關於C++實現訪問者模式的文章就介紹到這瞭,更多相關C++訪問者模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- .Net行為型設計模式之訪問者模式(Visitor)
- Java訪問者設計模式詳細講解
- C++使用標準庫實現事件和委托以及信號和槽機制
- java訪問者模式的靜態動態及偽動態分派徹底理解
- 超級詳細講解C++中的多態