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

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

C++設計模式之模板方法模式

2020-01-26 15:15:38
字體:
來源:轉載
供稿:網友

前言

離開了自己工作了將近兩年的公司,日子不再有了忙碌,可以閑下來,躺在家里的床上,想著以后的路怎么走,說實話,真的很迷茫,從2012年畢業到現在,時間不長,但是學到的東西真的是非常有限,一直從事于Windows平臺上的開發。說到Windows平臺的開發,大家都肯定知道的HOOK的,即使不知道HOOK,對于COM應該也是知道的,我的系列博文中也對COM進行過全面的總結。說白了,HOOK就是在執行某個功能時,會有一個一系列的執行過程,對于這個過程一般都是固定的,比如:第一步執行什么,第二步干什么,最后一步干什么,都是設計好的。而具體如何去完成每一步,都是可以由程序員去控制的。COM也是如此,COM是面對接口的,當完成某一個功能模塊時,就可能是系列接口的疊加調用,而接口的實現都是由程序員來控制的。說白了,一個功能模塊的實現流程是固定了,但是對于每一步的具體實現都是不固定的。對于這種需求,一般是如何來做的呢?從設計模式的角度來說,這個設計模式叫模板方法模式,可能你不知道這個設計模式的名字,但是,這種方法你已經用過了。現在我就對模板方法模式進行詳細的總結。

模板方法模式

在GOF的《設計模式:可復用面向對象軟件的基礎》一書中對模板方法模式是這樣說的:定義一個操作中的算法骨架,而將一些步驟延遲到子類中。TemplateMethod使得子類可以不改變一個算法的接口即可重定義改算法的某些特定步驟。

我結合我在實際開發項目中的一個例子來說說這個模板方法模式吧。我們曾經做過一款產品,這個產品類似于一個云端的文件管理客戶端。對于這樣的一個客戶端,由于其云端的服務器有三種,而每一種服務器之間的通信方式和對外公開的接口都是不是一致的,這就需要實現的客戶端要屏蔽云端服務器和接口的差異性,而提供統一的操作界面,所以在實現這個客戶端的同時,我們實現了一個框架,一個對于服務器和接口是通用的框架,比如就拿文件下載來說說。我們的實現大概如下:

復制代碼 代碼如下:

class FileOperation
{
public:
     bool DownloadFile(wchar_t *pSrc, wchar_t *pDest)
     {
          if (!pSrc || !pDest) return false;
          if (!DoBeginDownloadFile(pSrc, pDest)) return false;
          if (!DoDownloadFile(pSrc, pDest)) return false;
          if (!DoEndDownloadFile(pSrc, pDest)) return false;
     }
 
protected:
     virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
};
 
class HttpFileOperation : public FileOperation
{
protected:
     virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
};
 
class SOAPFileOperation : public FileOperation
{
protected:
     virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
     virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
};

下載文件的流程為:先調用DoBeginDownloadFile,執行下載文件之前的一些操作,再調用DoDownloadFile實現真正的文件下載,最后調用DoEndDownloadFile完成文件下載的清理工作。對于任何服務器,下載文件的這個流程是不會發生變化的。而在DoBeginDownloadFile、DoDownloadFile和DoEndDownloadFile的內部具體是如何實現的,由程序員根據具體的云端服務器和對外公開的接口來完成的。最終客戶端去完成文件下載操作時,只會調用DownloadFile函數就可以完成??梢钥吹?,在上面的代碼中,只有DownloadFile是public的,其它的操作函數都是protected。這也意味著,我們完成的框架對外只公開DownloadFile接口。

UML類圖

AbstractClass(抽象類):定義抽象的原語操作,具體的子類將重定義它們以實現一個算法的各步驟。主要是實現一個模板方法,定義一個算法的骨架。該模板方法不僅調用原語操作,也調用定義在AbstractClass或其他對象中的操作。
ConcreteClass(具體類):實現原語操作以完成算法中與特定子類相關的步驟。
由于在具體的子類ConcreteClass中重定義了實現一個算法的各步驟,而對于不變的算法流程則在AbstractClass的TemplateMethod中完成。

使用場合

模板方法是一種代碼復用的基本技術。它們在類庫中尤為重要,它們提取了類庫中的公共行為。在使用模板方法時,很重要的一點是模板方法應該指明哪些操作是可以被重定義的,以及哪些是必須被重定義的。要有效的重用一個抽象類,子類編寫者必須明確了解哪些操作是設計為有待重定義的。

代碼實現

這里就根據上面的類圖,對模板方法模式進行了簡單的實現。由于該模式非常簡單,所以也沒有更多的可以講的了。

復制代碼 代碼如下:

#include <iostream>
using namespace std;
 
class AbstractClass
{
public:
     void TemplateMethod()
     {
          PrimitiveOperation1();
          cout<<"TemplateMethod"<<endl;
          PrimitiveOperation2();
     }
 
protected:
     virtual void PrimitiveOperation1()
     {
          cout<<"Default Operation1"<<endl;
     }
 
     virtual void PrimitiveOperation2()
     {
          cout<<"Default Operation2"<<endl;
     }
};
 
class ConcreteClassA : public AbstractClass
{
protected:
          virtual void PrimitiveOperation1()
     {
          cout<<"ConcreteA Operation1"<<endl;
     }
 
     virtual void PrimitiveOperation2()
     {
          cout<<"ConcreteA Operation2"<<endl;
     }
};
 
class ConcreteClassB : public AbstractClass
{
protected:
          virtual void PrimitiveOperation1()
     {
          cout<<"ConcreteB Operation1"<<endl;
     }
 
     virtual void PrimitiveOperation2()
     {
          cout<<"ConcreteB Operation2"<<endl;
     }
};
 
int main()
{
     AbstractClass *pAbstractA = new ConcreteClassA;
     pAbstractA->TemplateMethod();
 
     AbstractClass *pAbstractB = new ConcreteClassB;
     pAbstractB->TemplateMethod();
 
     if (pAbstractA) delete pAbstractA;
     if (pAbstractB) delete pAbstractB;
}

總結

模板方法模式,總的來說很好接受,很好理解,沒有難點;對于此設計模式,我個人覺的還是可以和裝飾模式進行對比一下。還是有一些相似之處的。好了,該設計模式的講解就到此結束。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永年县| 凤山市| 鄂伦春自治旗| 北安市| 浦江县| 石景山区| 安西县| 金溪县| 慈溪市| 天门市| 平乐县| 旺苍县| 河津市| 新绛县| 高州市| 莱西市| 大同县| 嵩明县| 晋江市| 昌江| 高淳县| 德钦县| 逊克县| 青田县| 陇南市| 凉山| 青龙| 吴桥县| 中西区| 老河口市| 醴陵市| 利辛县| 邻水| 台前县| 济南市| 吉木萨尔县| 开化县| 渭源县| 麻栗坡县| 麻栗坡县| 锦屏县|