Visitor設計模式–學習總結

來源:互聯網
上載者:User

問題:

         在物件導向系統的開發和設計過程中,經常會遇到一種情況就是需求變更,這樣我們不得不去修改已有的設計,最常見的方法就是在實現好的類添加新的方法去實現客戶新的需求,這樣造成原來的設計根本就不可能封閉;

 

 

意圖:

表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

 

適用環境:

u       一個對象結構包含很多類對象,它們有不同的介面,而你想對這些對象實施一些依賴於其具體類的操作。

u       需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作“汙染”這些對象的類。Visitor 使得你可以將相關的操作集中起來定義在一個類中。當該對象結構被很多應用共用時,用Visitor 模式讓每個應用僅包含需要用到的操作。

u 定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。改變對象結構類需要重定義對所有訪問者的介面,這可能需要很大的代價。如果對象結構類經常改變,那麼可能還是在這些類中定義這些操作較好。

 

結構:

 

 

實現:

 

Element.h檔案

 

#pragma
once

class
Visitor;

 

class
Element

{

public:

     Element(void);

     virtual ~Element(void);

     virtual
void Accept(Visitor*vis)=0;

};

 

class
ConcreteElementA:publicElement

{

public:

     ConcreteElementA();

     ~ConcreteElementA();

     void
Accept(Visitor *vis);

 

};

 

class
ConcreteElementB:publicElement

{

public:

     ConcreteElementB();

     ~ConcreteElementB();

     void
Accept(Visitor *vis);

 

};

 

Element.cpp檔案

 

#include
"StdAfx.h"

#include
"Element.h"

#include
"Visitor.h"

#include
<iostream>

using namespace
std;

 

Element::Element(void)

{

}

 

Element::~Element(void)

{

}

 

void
Element::Accept(Visitor *vis)

{

 

}

 

ConcreteElementA::ConcreteElementA()

{

 

}

 

ConcreteElementA::~ConcreteElementA()

{

 

}

 

void
ConcreteElementA::Accept(Visitor *vis)

{

     vis->visitConcreteElementA(this);

     cout<<"visitingConcreteElementA...."<<endl;

}

 

ConcreteElementB::ConcreteElementB()

{

 

}

 

ConcreteElementB::~ConcreteElementB()

{

 

}

 

void
ConcreteElementB::Accept(Visitor *vis)

{

     vis->visitConcreteElementB(this);

     cout<<"visitingConcreteElementB...."<<endl;

}

 

Visitor.h檔案

#pragma
once

 

class
ConcreteElementA;

class
ConcreteElementA;

class
Element;

 

class
Visitor

{

public:

     Visitor(void);

     virtual ~Visitor(void);

 

     virtual
void visitConcreteElementA(Element*elm)=0;

     virtual
void visitConcreteElementB(Element*elm)=0;

 

};

 

class
ConcreteVisitorA:publicVisitor

{

public:

     ConcreteVisitorA();

     virtual ~ConcreteVisitorA();

     virtual
void visitConcreteElementA(Element*elm);

     virtual
void visitConcreteElementB(Element*elm);

 

};

 

class
ConcreteVisitorB:publicVisitor

{

public:

     ConcreteVisitorB();

     virtual ~ConcreteVisitorB();

     virtual
void visitConcreteElementA(Element*elm);

     virtual
void visitConcreteElementB(Element*elm);

 

};

 

Visitor.cpp檔案

 

#include
"StdAfx.h"

#include
"Visitor.h"

#include
"Element.h"

 

#include
<iostream>

using namespace
std;

 

Visitor::Visitor(void)

{

}

 

Visitor::~Visitor(void)

{

}

 

ConcreteVisitorA::ConcreteVisitorA()

{

}

 

ConcreteVisitorA::~ConcreteVisitorA()

{

}

 

void
ConcreteVisitorA::visitConcreteElementA(Element *elm)

{

     cout<<"iwill visit ConcreteElementA...."<<endl;

}

 

void
ConcreteVisitorA::visitConcreteElementB(Element *elm)

{

     cout<<"iwill visit ConcreteElementB...."<<endl;

}

 

 

ConcreteVisitorB::ConcreteVisitorB()

{

}

 

ConcreteVisitorB::~ConcreteVisitorB()

{

}

 

void
ConcreteVisitorB::visitConcreteElementA(Element *elm)

{

     cout<<"iwill visit ConcreteElementA...."<<endl;

}

 

void
ConcreteVisitorB::visitConcreteElementB(Element *elm)

{

     cout<<"iwill visit ConcreteElementB...."<<endl;

}

 

調用主函數:

// VisitorPattern.cpp : 定義控制台應用程式的進入點。

//

 

#include
"stdafx.h"

#include
"Visitor.h"

#include
"Element.h"

 

#include
<iostream>

using namespace
std;

 

int _tmain(int
argc, _TCHAR*
argv[])

{

     Visitor *vis=new
ConcreteVisitorA();

     Element *elm=new
ConcreteElementA();

     elm->Accept(vis);

     return 0;

}

 

 

代碼理解:

       在Visitor模式中Accept()操作時一個雙指派的操作。具體調用哪一個具體的Accept()操作,有2個決定因素:1)Element的類型。因為Accept()是多態的操作,需要具

體的Element 類型的子類才可以決定到底調用哪一個 Accept()實現;2)Visitor的類型。

Accept()操作有一個參數(Visitor*vis) ,要決定了實際傳進來的 Visitor 的實體類別才

以決定具體是調用哪個VisitConcrete()實現。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.