1. 程式人生 > >設計模式---訪問者模式(C++實現)

設計模式---訪問者模式(C++實現)

/*************************************************************************************************************
適用於:
把資料結構 和 作用於資料結構上的操作 進行解耦合;
適用於資料結構比較穩定的場合
訪問者模式總結:
訪問者模式優點是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。
訪問者模式將有關的行為集中到一個訪問者物件中。那訪問者模式的缺點是是增加新的資料結構變得困難了


實現資料結構   和操作資料結構的動作     進行有效的分離
實現方法: 
分別定義訪問者介面(資料結構的基類指標)    公園部分訪問介面(訪問者的指標介面)+  接受訪問的內部實現了訪問函式的呼叫
如果要管理訪問者增加超級訪問者,使用集合將其封裝,然後遍歷集合
**************************************************************************************************************/
/*案例需求:
比如有一個公園,有一到多個不同的組成部分;該公園存在多個訪問者:清潔工A負責打掃公園的A部分,清潔工B負責打掃公園的B部分,
公園的管理者負責檢點各項事務是否完成,上級領導可以視察公園等等。也就是說,對於同一個公園,不同的訪問者有不同的行為操作,
而且訪問者的種類也可能需要根據時間的推移而變化(行為的擴充套件性)*/
#include <iostream>
#include <list>
#include <string>
using namespace std;
class  ParkElement;
class Visitor//不同的訪問者 訪問公園完成不同的動作 
{
public:
virtual void visit(ParkElement *park) = 0;
};
class ParkElement//公園不同的部分接受不同的訪問者
{
public:
virtual void accept(Visitor *v) = 0;
};
class ParkA : public ParkElement  //公園A部分接受訪問者
{
public:
virtual void accept(Visitor *v){
v->visit(this);}//傳來的誰,去回撥它是訪問函式
};
class ParkB : public ParkElement//公園B部分接受訪問者
{
public:
virtual void accept(Visitor *v){
v->visit(this);}
};
class Park : public ParkElement
{//公園的部分可以進行集中管理
public:
Park(){
m_list.clear();}
void setPart(ParkElement *e){
m_list.push_back(e);}
public:
void accept(Visitor *v)
{
for (list<ParkElement *>::iterator it = m_list.begin(); it != m_list.end(); it++)
{(*it)->accept(v);}
}
private:
list<ParkElement *> m_list;
};
class VisitorA : public Visitor//訪問者A
{
public:
virtual void visit(ParkElement *park){
cout << "清潔工A 訪問 公園A 部分,打掃衛生完畢" << endl;}
};


class VisitorB : public Visitor//訪問者B
{
public:
virtual void visit(ParkElement *park){
cout << "清潔工B 訪問 公園B 部分,打掃衛生完畢" << endl;}
};
class VisitorManager : public Visitor//訪問者管理員
{
public:
virtual void visit(ParkElement *park)
{cout << "管理員 檢查 此部分衛生情況" << endl;}
};


void main()
{
VisitorA *visitorA = new VisitorA;//建立訪問者A
VisitorB *visitorB = new VisitorB;//建立訪問者B


ParkA *partA = new ParkA;//建立資料結構  A
ParkB *partB = new ParkB;//建立資料結構  B


partA->accept(visitorA);//公園接受訪問者A訪問 +在這個函式中封裝了visitorA去訪問公園A部分
partB->accept(visitorB);//公園接受訪問者B訪問 + 在這個函式中封裝了visitorA去訪問公園B部分


VisitorManager *visitorManager = new VisitorManager;
Park * park = new Park;
park->setPart(partA);  //將A部分加入容器
park->setPart(partB);  //將B部分加入容器
park->accept(visitorManager); //管理員去檢查A部分 +  管理員去檢查B部分
//遍歷容器,接受visitorManager訪問,去呼叫visitorManager的訪問函式
system("pause");

}

參考:傳智播客--王保明