訪問者模式(visitor),表示一個作用于某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。訪問者模式適用于數據結構相對穩定的系統。它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化。訪問者模式的目的是要把處理從數據結構分離出來。很多系統可以按照算法和數據結構分開,如果這樣的系統有比較穩定的數據結構,又有易于變化的算法的話,使用訪問者模式就是比較合適的,因為訪問者模式使得算法操作的增加變得容易。反之,如果這樣的系統的數據結構對象易于變化,經常要有新的數據對象增加進來,就不適合使用訪問者模式。
訪問者模式的優點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關的行為集中到一個訪問者對象中。通常concreteVisitor可以單獨開發,不必跟concreteElement寫在一起。訪問者的缺點其實也就是使增加新的數據結構變得困難了。
結構圖:
訪問者模式基本示例代碼
訪問者模式 visitor.h、concreteVisitor.h、element.h、concreteElement.h、objectStructure.h
客戶端 visitorApp.cpp
訪問者模式
visitor.h/************************************************************************ * description: 為該對象結構中ConcreteElement的每一個類聲明一個visit操作 * remark: ************************************************************************/ #ifndef _VISITOR_H_ #define _VISITOR_H_ class concreteElementA; class concreteElementB; class visitor { public: visitor(){}; virtual ~visitor(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) = 0; virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) = 0; }; #endif// _VISITOR_H_
concreteVisitor.h
/************************************************************************ * description: 具體訪問者,實現每個由visitor聲明的操作。每個操作實現算法 的一部分,而該算法片斷乃是對應于結構中對象的類 * remark: ************************************************************************/ #ifndef _CONCRETE_VISITOR_H_ #define _CONCRETE_VISITOR_H_ #include "visitor.h" #include <iostream> using namespace std; class concreteVisitor1 : public visitor { public: concreteVisitor1(){}; ~concreteVisitor1(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) { cout << "concreteElementA被concreteVisitor1訪問" << endl; } virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) { cout << "concreteElementB被concreteVisitor1訪問" << endl; } }; class concreteVisitor2 : public visitor { public: concreteVisitor2(){}; ~concreteVisitor2(){}; virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) { cout << "concreteElementA被concreteVisitor2訪問" << endl; } virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) { cout << "concreteElementB被concreteVisitor2訪問" << endl; } }; #endif// _CONCRETE_VISITOR_H_
element.h
/************************************************************************ * description: 定義一個accept操作,它以一個訪問者為參數 * remark: ************************************************************************/ #ifndef _ELEMENT_H_ #define _ELEMENT_H_ class visitor; class element { public: element(){}; virtual ~element(){}; virtual void accept(visitor* pVisitor) = 0; }; #endif// _ELEMENT_H_
concreteElement.h
#ifndef _CONCRETE_ELEMENT_H_ #define _CONCRETE_ELEMENT_H_ #include "element.h" #include <iostream> using namespace std; class concreteElementA : public element { public: concreteElementA(){}; ~concreteElementA(){}; // 充分利用雙分派技術,實現處理與數據結構的分離 virtual void accept(visitor* pVisitor) { if (NULL != pVisitor) { pVisitor->visitConcreteElementA(this); } } // 其他的相關方法 void operationA() { cout << "具體元素A的其他相關方法" << endl; } }; class concreteElementB : public element { public: concreteElementB(){}; ~concreteElementB(){}; // 充分利用雙分派技術,實現處理與數據結構的分離 virtual void accept(visitor* pVisitor) { if (NULL != pVisitor) { pVisitor->visitConcreteElementB(this); } } // 其他的相關方法 void operationB() { cout << "具體元素B的其他相關方法" << endl; } }; #endif// _CONCRETE_ELEMENT_H_
objectStructure.h
/************************************************************************ * description: 枚舉元素,可以提供一個高層的接口以允許訪問者訪問它的元素 * remark: ************************************************************************/ #ifndef _OBJECT_STRUCTURE_H_ #define _OBJECT_STRUCTURE_H_ #include "element.h" #include "visitor.h" #include <list> using namespace std; class objectStructure { public: void attach(element* pElement) { m_list.push_back(pElement); } void detach(element* pElement) { m_list.remove(pElement); } void accept(visitor* pVisitor) { list<element*>::iterator Iter; for (Iter = m_list.begin(); Iter != m_list.end(); ++Iter) { if (NULL != *Iter) { (*Iter)->accept(pVisitor); } } } private: list<element*> m_list; }; #endif// _OBJECT_STRUCTURE_H_
客戶端
visitorApp.cpp
// visitorApp.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include "objectStructure.h" #include "concreteElement.h" #include "concreteVisitor.h" void freePtr(void* vptr) { if (NULL != vptr) { delete vptr; vptr = NULL; } } int _tmain(int argc, _TCHAR* argv[]) { objectStructure* pObject = new objectStructure(); if (NULL != pObject) { element* pElementA = new concreteElementA(); element* pElementB = new concreteElementB(); pObject->attach(pElementA); pObject->attach(pElementB); concreteVisitor1* pVisitor1 = NULL; pVisitor1 = new concreteVisitor1(); concreteVisitor2* pVisitor2 = NULL; pVisitor2 = new concreteVisitor2(); pObject->accept(pVisitor1); pObject->accept(pVisitor2); system("pause"); freePtr(pVisitor2); freePtr(pVisitor1); freePtr(pElementB); freePtr(pElementA); freePtr(pObject); } return 0; }
使用訪問者模式的優點和缺點
訪問者模式有如下的優點:
訪問者模式有如下的缺點:
訪問者模式的適用場景:
新聞熱點
疑難解答
圖片精選