C++實現(xiàn)訪問者模式的基礎(chǔ)介紹
一、訪問者模式基礎(chǔ)知識
1.1 模式動機
對于系統(tǒng)中的某些對象中可能存在多種不同類型的元素,而且不同的調(diào)用者使用這些元素時也有所區(qū)別,這些調(diào)用者稱為訪問者。
訪問者模式(Visitor Pattern):表示一個作用于某對象結(jié)構(gòu)中各元素的操作,它使我們可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
訪問者模式的應(yīng)用場景:
- 訪問者模式適用于數(shù)據(jù)結(jié)構(gòu)相對穩(wěn)定的系統(tǒng)
- 它把數(shù)據(jù)結(jié)構(gòu)和作用于數(shù)據(jù)結(jié)構(gòu)之上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。
- 訪問者模式的目的是要把處理從數(shù)據(jù)結(jié)構(gòu)分離出來。如果這樣的系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),又有已與變化的算法的話,使用訪問者模式就是比較合適的,因為訪問者模式使得算法操作的增加變得更容易。反之亦然。
1.2 訪問者模式結(jié)構(gòu)
訪問者模式中對象結(jié)構(gòu)存儲了不同類型的元素對象,以提供不同訪問者訪問。訪問者模式包括兩個層次結(jié)構(gòu),一個是訪問者層次結(jié)構(gòu),提供了抽象訪問者和具體訪問者,一個是元素層次結(jié)構(gòu),提供了抽象元素和具體元素。
相同的訪問者可以以不同的方式訪問不同的元素,相同的元素可以接受不同訪問者以不同的方式訪問。
(1)Visitor (抽象訪問者)
抽象訪問者為對象結(jié)構(gòu)類中每一個具體元素類聲明一個訪問操作。
(2)ConcreteVisitor (具體訪問者)
具體訪問者實現(xiàn)了每個由抽象訪問者聲明的操作,每一個操作用于訪問對象結(jié)構(gòu)中一種元素類型的元素。
(3)Element(抽象元素)
抽象元素一般是抽象類或接口,定義一個accept()方法,該方法以一個抽象訪問者作為參數(shù)。
(4)ConcreteElement (具體元素)
具體訪問者實現(xiàn)了accept()方法,在其accept()
(5)ObjectStructure(對象結(jié)構(gòu))
對象結(jié)構(gòu)是一個元素的集合,它用于存放元素對象,并且提供了遍歷其內(nèi)部元素的方法。
1.3 訪問者模式優(yōu)缺點
訪問者模式優(yōu)點:
- 訪問者模式的優(yōu)點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關(guān)的行為集中到一個訪問者對象中。
模式的缺點:
- 使增加新的元素類變得困難。在訪問者模式中,每增加一個新的元素都意味著要在抽象訪問者角色中增加一個新的抽象操作,并在每一個具體訪問者中增加相應(yīng)的具體操作,違背“開閉原則”的要求。
1.4 訪問者模式應(yīng)用
#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){ // 現(xiàn)在根據(jù)傳進來的pElementA,可以對ConcreteElementA中的element進行操作 } void VisitConcreteElementB(ConcreteElementB *pElementB){ // 現(xiàn)在根據(jù)傳進來的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用于接受訪問者的訪問 }; /*具體元素類 通過調(diào)用Visitor類的visit()方法實現(xiàn)對元素的訪問*/ class ConcreteElementA : public Element { public: void Accept(Visitor *pVisitor)//通過調(diào)用visitor對象的 visit()方法實現(xiàn)對元素對象的訪問 { pVisitor->VisitConcreteElementA(this); } }; /*具體元素類 */ class ConcreteElementB : public Element { public: void Accept(Visitor *pVisitor) { pVisitor->VisitConcreteElementB(this); } }; // ObjectStructure類(對象結(jié)構(gòu)類),能枚舉它的元素,可以提供一個高層的接口以允許訪問者訪問它的元素 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設(shè)置visitor,進行對應(yīng)的操作 for (vector<Element *>::const_iterator it = elements.begin(); it != elements.end(); ++it) { (*it)->Accept(pVisitor); } } int main() { //實例化對象結(jié)構(gòu),用于存放元素對象,提供遍歷其內(nèi)部元素的方法 ObjectStructure *pObject = new ObjectStructure; //實例化具體元素 并將創(chuàng)建好的元素放入對象結(jié)構(gòu)中 ConcreteElementA *pElementA = new ConcreteElementA; ConcreteElementB *pElementB = new ConcreteElementB; pObject->Attach(pElementA); pObject->Attach(pElementB); //實例化訪問者 ConcreteVisitor1 *pVisitor1 = new ConcreteVisitor1; ConcreteVisitor2 *pVisitor2 = new ConcreteVisitor2; //調(diào)用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++實現(xiàn)):訪問者模式(c++實現(xiàn))
【2】C++設(shè)計模式之訪問者模式: http://chabaoo.cn/article/55999.htm
到此這篇關(guān)于C++實現(xiàn)訪問者模式的文章就介紹到這了,更多相關(guān)C++訪問者模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入解析C++中的動態(tài)類型轉(zhuǎn)換與靜態(tài)類型轉(zhuǎn)換運算符
這篇文章主要介紹了C++中的動態(tài)類型轉(zhuǎn)換與靜態(tài)類型轉(zhuǎn)換運算符,即dynamic_cast與static_cast的用法,需要的朋友可以參考下2016-01-01C語言實現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表
這篇文章主要為大家詳細介紹了c語言實現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11