国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

詳解C++設計模式編程中對訪問者模式的運用

2020-05-23 14:06:33
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++設計模式編程中對訪問者模式的運用,訪問者模式在不破壞類的前提下為類提供增加新的新操作,需要的朋友可以參考下
 

訪問者模式(visitor),表示一個作用于某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。訪問者模式適用于數據結構相對穩定的系統。它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由地演化。訪問者模式的目的是要把處理從數據結構分離出來。很多系統可以按照算法和數據結構分開,如果這樣的系統有比較穩定的數據結構,又有易于變化的算法的話,使用訪問者模式就是比較合適的,因為訪問者模式使得算法操作的增加變得容易。反之,如果這樣的系統的數據結構對象易于變化,經常要有新的數據對象增加進來,就不適合使用訪問者模式。

訪問者模式的優點就是增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關的行為集中到一個訪問者對象中。通常concreteVisitor可以單獨開發,不必跟concreteElement寫在一起。訪問者的缺點其實也就是使增加新的數據結構變得困難了。

結構圖:

C++設計模式編程,對訪問者模式

訪問者模式基本示例代碼

訪問者模式 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; } 

使用訪問者模式的優點和缺點

訪問者模式有如下的優點:

  • 訪問者模式使得增加新的操作變得很容易。如果一些操作依賴于一個復雜的結構對象的話,那么一般而言,增加新的操作會很復雜。而使用訪問者模式,增加新的操作就意味著增加一個新的訪問者類,因此,變得很容易。
  • 訪問者模式將有關的行為集中到一個訪問者對象中,而不是分散到一個個的節點類中。
  • 訪問者模式可以跨過幾個類的等級結構訪問屬于不同的等級結構的成員類。迭代子只能訪問屬于同一個類型等級結構的成員對象,而不能訪問屬于不同等級結構的對象。訪問者模式可以做到這一點。
  • 積累狀態。每一個單獨的訪問者對象都集中了相關的行為,從而也就可以在訪問的過程中將執行操作的狀態積累在自己內部,而不是分散到很多的節點對象中。這是有益于系統維護的優點。

訪問者模式有如下的缺點:

  • 增加新的節點類變得很困難。每增加一個新的節點都意味著要在抽象訪問者角色中增加一個新的抽象操作,并在每一個具體訪問者類中增加相應的具體操作。
  • 破壞封裝。訪問者模式要求訪問者對象訪問并調用每一個節點對象的操作,這隱含了一個對所有節點對象的要求:它們必須暴露一些自己的操作和內部狀態。不然,訪問者的訪問就變得沒有意義。由于訪問者對象自己會積累訪問操作所需的狀態,從而使這些狀態不再存儲在節點對象中,這也是破壞封裝的。

訪問者模式的適用場景:

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲阳县| 和龙市| 门头沟区| 墨竹工卡县| 淳化县| 深水埗区| 滁州市| 普宁市| 正阳县| 涞水县| 娄底市| 云浮市| 滨海县| 武宣县| 桑日县| 民和| 五原县| 华宁县| 邢台市| 德钦县| 姚安县| 六盘水市| 宁陵县| 巴楚县| 驻马店市| 托里县| 山东| 南通市| 信宜市| 扶风县| 伽师县| 巢湖市| 九龙城区| 和林格尔县| 田林县| 郸城县| 洪江市| 城步| 玛多县| 清丰县| 陆丰市|