1. 程式人生 > >設計模式(23)-行為型模式-VISITOR模式

設計模式(23)-行為型模式-VISITOR模式

3.11.1功能

在面向物件系統的開發和設計過程,經常會遇到一種情況就是需求變更(ChangeRequest),經常我們做好的一個設計、實現了一個系統原型,咱們的客戶又會有了新的需求。我們又因此不得不去修改已有的設計,最常見就是解決方案就是給已經設計、實現好的類新增新的方法去實現客戶新的需求,這樣就陷入了設計變更的夢魘:不停地打補丁,其帶來的後果就是設計根本就不可能封閉、編譯永遠都是整個系統程式碼。

Visitor模式則提供了一種解決方案:將更新(變更)封裝到一個類中(Vistor),並由待更改類提供一個接收介面,則可達到效果。

3.11.2 結構圖


•  Vi s i t o r(訪問者,如N o d e Vi s i t o r)
— 為該物件結構中C o n c r e t e E l e m e n t的每一個類宣告一個Vi s i t 操作。該操作的名字和特徵標識了傳送Vi s i t 請求給哪個訪問者。

•  C o n c r e t e Vi s i t o r(具體訪問者,如 Ty p e C h e c k i ng Vi s i t o r)
— 實現每個由Vi s i t o r 宣告的操作。每個操作實現本演算法的一部分,而該演算法片斷乃是對應於結構中物件的類。

•  E l e m e n t(元素,如 N o d e)
— 定義一個Ac c e p t操作,它以一個訪問者為引數。


•  C o n c r e t e E l e m e n t(具體元素,如As s i g n m e n t N o d e,Va r i a b l e R e f N o d e)
— 實現Ac c e p t操作,該操作以一個訪問者為引數。

•  O b j e c t S t r u c t u r e
— 能列舉它的元素。
— 可以提供一個高層的介面以允許該訪問者訪問它的元素。
— 可以是一個複合(參見C o m p o s i t e(4. 3) )或是一個集合,如一個列表或一個無序集合。

3.11.3 協作


• 一個使用Vi s i t o r 模式的客戶必須建立一個C o n c r e t e Vi s i t o r物件,然後遍歷該物件結構,並用該訪問者訪問每一個元素。

• 當一個元素被訪問時,它呼叫對應於它的類的Vi s i t o r操作。如果必要,該元素將自身作為這個操作的一個引數以便該訪問者訪問它的狀態。

3.11.4 C++程式碼示例

//Visitor.h

#ifndef _VISITOR_H_

#define _VISITOR_H_

class ConcreteElementA;

class ConcreteElementB;

class Element;

class Visitor

{

public:

       virtual ~Visitor();

       virtual void

              VisitConcreteElementA(Element* elm) = 0;

       virtual void

              VisitConcreteElementB(Element* elm) = 0;

protected:

       Visitor();

private:

};

class ConcreteVisitorA :public Visitor

{

public:

       ConcreteVisitorA();

       virtual ~ConcreteVisitorA();

       virtual void

              VisitConcreteElementA(Element* elm);

       virtual void

              VisitConcreteElementB(Element* elm);

protected:

private:

};

class ConcreteVisitorB :public Visitor

{

public:

       ConcreteVisitorB();

       virtual ~ConcreteVisitorB();

       virtual void

              VisitConcreteElementA(Element* elm);

       virtual void

              VisitConcreteElementB(Element* elm);

protected:

private:

};

#endif //~_VISITOR_H_

//Visitor.cpp

#include "Visitor.h"

#include "Element.h"

#include <iostream>

using namespace std;

Visitor::Visitor()

{

}

Visitor::~Visitor()

{

}

ConcreteVisitorA::ConcreteVisitorA()

{

}

ConcreteVisitorA::~ConcreteVisitorA()

{

}

void ConcreteVisitorA::VisitConcreteElementA(Element* elm)

{

       cout << "i willvisit ConcreteElementA..."<<endl;

}

void

ConcreteVisitorA::VisitConcreteElementB(Element*elm)

{

       cout << "i will  visitConcreteElementB..."<<endl;

}

ConcreteVisitorB::ConcreteVisitorB()

{

}

ConcreteVisitorB::~ConcreteVisitorB()

{

}

void ConcreteVisitorB::VisitConcreteElementA(Element* elm)

{

       cout << "i will  visitConcreteElementA..."<<endl;

}

void ConcreteVisitorB::VisitConcreteElementB(Element* elm)

{

       cout << "i will visit ConcreteElementB..."<<endl;

}

//Element.h

#ifndef _ELEMENT_H_

#define _ELEMENT_H_

class Visitor;

class Element

{

public:

       virtual ~Element();

       virtual void Accept(Visitor*vis) = 0;

protected:

       Element();

private:

};

class ConcreteElementA :public Element

{

public:

       ConcreteElementA();

       ~ConcreteElementA();

       void Accept(Visitor* vis);

protected:

private:

};

class ConcreteElementB :public Element

{

public:

       ConcreteElementB();

       ~ConcreteElementB();

       void Accept(Visitor* vis);

protected:

private:

};

#endif //~_ELEMENT_H_

//Element.cpp

#include"Element.h"

#include"Visitor.h"

#include<iostream>

using namespace std;

Element::Element()

{

}

Element::~Element()

{

}

void Element::Accept(Visitor*vis)

{

}

ConcreteElementA::ConcreteElementA()

{

}

ConcreteElementA::~ConcreteElementA()

{

}

void ConcreteElementA::Accept(Visitor* vis)

{

       vis->VisitConcreteElementA(this);

       cout << "visiting ConcreteElementA..."<<endl;

}

ConcreteElementB::ConcreteElementB()

{

}

ConcreteElementB::~ConcreteElementB()

{

}

void ConcreteElementB::Accept(Visitor* vis)

{

       cout << "visiting ConcreteElementB..."<<endl;

              vis->VisitConcreteElementB(this);

}

//main.cpp
#include"Element.h" #include"Visitor.h" #include<iostream> using namespace std;

int main(int argc, char*argv[])

{

       Visitor* vis = new ConcreteVisitorA();

       Element*elm = new

              ConcreteElementA();

       elm->Accept(vis);

       return 0;

}