訪問者模式(Visitor):表示一個作用於某物件結構中的各元素的操作,它使你可你在不改變各元素類別的前提下定義作用於這些元素的新操作。
五個角色類別:
Visitor:為該物件結構中ConcreteElement的每一個類別宣告一個Visit操作。
ConcreteVistor:具體訪客,實作每個由Visitor聲明的操作。每個操作實現演算法的一部分,而該演算法片段是對應於結構中物件的類別。
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中文網(www.php.cn)!