最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++設(shè)計(jì)模式編程中對(duì)訪問(wèn)者模式的運(yùn)用

 更新時(shí)間:2016年03月16日 11:18:47   作者:freshow  
這篇文章主要介紹了C++設(shè)計(jì)模式編程中對(duì)訪問(wèn)者模式的運(yùn)用,訪問(wèn)者模式在不破壞類的前提下為類提供增加新的新操作,需要的朋友可以參考下

訪問(wèn)者模式(visitor),表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。訪問(wèn)者模式適用于數(shù)據(jù)結(jié)構(gòu)相對(duì)穩(wěn)定的系統(tǒng)。它把數(shù)據(jù)結(jié)構(gòu)和作用于結(jié)構(gòu)上的操作之間的耦合解脫開(kāi),使得操作集合可以相對(duì)自由地演化。訪問(wèn)者模式的目的是要把處理從數(shù)據(jù)結(jié)構(gòu)分離出來(lái)。很多系統(tǒng)可以按照算法和數(shù)據(jù)結(jié)構(gòu)分開(kāi),如果這樣的系統(tǒng)有比較穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),又有易于變化的算法的話,使用訪問(wèn)者模式就是比較合適的,因?yàn)樵L問(wèn)者模式使得算法操作的增加變得容易。反之,如果這樣的系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)對(duì)象易于變化,經(jīng)常要有新的數(shù)據(jù)對(duì)象增加進(jìn)來(lái),就不適合使用訪問(wèn)者模式。

訪問(wèn)者模式的優(yōu)點(diǎn)就是增加新的操作很容易,因?yàn)樵黾有碌牟僮骶鸵馕吨黾右粋€(gè)新的訪問(wèn)者。訪問(wèn)者模式將有關(guān)的行為集中到一個(gè)訪問(wèn)者對(duì)象中。通常concreteVisitor可以單獨(dú)開(kāi)發(fā),不必跟concreteElement寫在一起。訪問(wèn)者的缺點(diǎn)其實(shí)也就是使增加新的數(shù)據(jù)結(jié)構(gòu)變得困難了。

結(jié)構(gòu)圖:

2016316111637382.jpg (734×565)

訪問(wèn)者模式基本示例代碼

訪問(wèn)者模式 visitor.h、concreteVisitor.h、element.h、concreteElement.h、objectStructure.h

客戶端 visitorApp.cpp

訪問(wèn)者模式

visitor.h
/************************************************************************ 
 * description: 為該對(duì)象結(jié)構(gòu)中ConcreteElement的每一個(gè)類聲明一個(gè)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: 具體訪問(wèn)者,實(shí)現(xiàn)每個(gè)由visitor聲明的操作。每個(gè)操作實(shí)現(xiàn)算法 
    的一部分,而該算法片斷乃是對(duì)應(yīng)于結(jié)構(gòu)中對(duì)象的類 
 * 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訪問(wèn)" << endl;  
 } 
 virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) 
 { 
  cout << "concreteElementB被concreteVisitor1訪問(wèn)" << endl;   
 } 
}; 
 
class concreteVisitor2 : public visitor 
{ 
public: 
 concreteVisitor2(){}; 
 ~concreteVisitor2(){}; 
 virtual void visitConcreteElementA(concreteElementA* pConcreteElementA) 
 { 
  cout << "concreteElementA被concreteVisitor2訪問(wèn)" << endl;  
 } 
 virtual void visitConcreteElementB(concreteElementB* pConcreteElementB) 
 { 
  cout << "concreteElementB被concreteVisitor2訪問(wèn)" << endl;   
 } 
}; 
#endif// _CONCRETE_VISITOR_H_ 

element.h

/************************************************************************ 
 * description: 定義一個(gè)accept操作,它以一個(gè)訪問(wèn)者為參數(shù) 
 * 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(){}; 
 // 充分利用雙分派技術(shù),實(shí)現(xiàn)處理與數(shù)據(jù)結(jié)構(gòu)的分離 
 virtual void accept(visitor* pVisitor) 
 { 
  if (NULL != pVisitor) 
  { 
   pVisitor->visitConcreteElementA(this); 
  } 
 } 
 // 其他的相關(guān)方法 
 void operationA() 
 { 
  cout << "具體元素A的其他相關(guān)方法" << endl; 
 } 
}; 
class concreteElementB : public element 
{ 
public: 
 concreteElementB(){}; 
 ~concreteElementB(){}; 
 // 充分利用雙分派技術(shù),實(shí)現(xiàn)處理與數(shù)據(jù)結(jié)構(gòu)的分離 
 virtual void accept(visitor* pVisitor) 
 { 
  if (NULL != pVisitor) 
  { 
   pVisitor->visitConcreteElementB(this); 
  } 
 } 
 // 其他的相關(guān)方法 
 void operationB() 
 { 
  cout << "具體元素B的其他相關(guān)方法" << endl; 
 } 
}; 
#endif// _CONCRETE_ELEMENT_H_ 

 

objectStructure.h

/************************************************************************ 
 * description: 枚舉元素,可以提供一個(gè)高層的接口以允許訪問(wèn)者訪問(wèn)它的元素 
 * 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 : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 
// 
#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; 
} 

使用訪問(wèn)者模式的優(yōu)點(diǎn)和缺點(diǎn)

訪問(wèn)者模式有如下的優(yōu)點(diǎn):

  • 訪問(wèn)者模式使得增加新的操作變得很容易。如果一些操作依賴于一個(gè)復(fù)雜的結(jié)構(gòu)對(duì)象的話,那么一般而言,增加新的操作會(huì)很復(fù)雜。而使用訪問(wèn)者模式,增加新的操作就意味著增加一個(gè)新的訪問(wèn)者類,因此,變得很容易。
  • 訪問(wèn)者模式將有關(guān)的行為集中到一個(gè)訪問(wèn)者對(duì)象中,而不是分散到一個(gè)個(gè)的節(jié)點(diǎn)類中。
  • 訪問(wèn)者模式可以跨過(guò)幾個(gè)類的等級(jí)結(jié)構(gòu)訪問(wèn)屬于不同的等級(jí)結(jié)構(gòu)的成員類。迭代子只能訪問(wèn)屬于同一個(gè)類型等級(jí)結(jié)構(gòu)的成員對(duì)象,而不能訪問(wèn)屬于不同等級(jí)結(jié)構(gòu)的對(duì)象。訪問(wèn)者模式可以做到這一點(diǎn)。
  • 積累狀態(tài)。每一個(gè)單獨(dú)的訪問(wèn)者對(duì)象都集中了相關(guān)的行為,從而也就可以在訪問(wèn)的過(guò)程中將執(zhí)行操作的狀態(tài)積累在自己內(nèi)部,而不是分散到很多的節(jié)點(diǎn)對(duì)象中。這是有益于系統(tǒng)維護(hù)的優(yōu)點(diǎn)。

訪問(wèn)者模式有如下的缺點(diǎn):

  • 增加新的節(jié)點(diǎn)類變得很困難。每增加一個(gè)新的節(jié)點(diǎn)都意味著要在抽象訪問(wèn)者角色中增加一個(gè)新的抽象操作,并在每一個(gè)具體訪問(wèn)者類中增加相應(yīng)的具體操作。
  • 破壞封裝。訪問(wèn)者模式要求訪問(wèn)者對(duì)象訪問(wèn)并調(diào)用每一個(gè)節(jié)點(diǎn)對(duì)象的操作,這隱含了一個(gè)對(duì)所有節(jié)點(diǎn)對(duì)象的要求:它們必須暴露一些自己的操作和內(nèi)部狀態(tài)。不然,訪問(wèn)者的訪問(wèn)就變得沒(méi)有意義。由于訪問(wèn)者對(duì)象自己會(huì)積累訪問(wèn)操作所需的狀態(tài),從而使這些狀態(tài)不再存儲(chǔ)在節(jié)點(diǎn)對(duì)象中,這也是破壞封裝的。

訪問(wèn)者模式的適用場(chǎng)景:

  • 一個(gè)對(duì)象結(jié)構(gòu)包含很多類對(duì)象,它們有不同的接口,而你想對(duì)這些對(duì)象實(shí)施一些依賴于其具體類的操作。
  • 需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對(duì)象的類。Vi s i t o r 使得你可以將相關(guān)的操作集中起來(lái)定義在一個(gè)類中。當(dāng)該對(duì)象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用Vi s i t o r 模式讓每個(gè)應(yīng)用僅包含需要用到的操作。
  • 定義對(duì)象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對(duì)象結(jié)構(gòu)類需要重定義對(duì)所有訪問(wèn)者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。

相關(guān)文章

最新評(píng)論

平定县| 桓台县| 饶河县| 彝良县| 漳平市| 延庆县| 郯城县| 鸡西市| 盘山县| 马公市| 济阳县| 巴彦县| 白河县| 白山市| 瓮安县| 五原县| 曲沃县| 建水县| 房产| 南乐县| 安宁市| 滨州市| 鹤壁市| 洪湖市| 平乐县| 龙胜| 枣强县| 城固县| 吉首市| 永福县| 璧山县| 吉隆县| 宽甸| 静安区| 永吉县| 芦山县| 阿克陶县| 东城区| 丹棱县| 嵊泗县| 江达县|