這是Bwar在2009年寫的設計模式C++實現,代碼都可編譯可運行,一直存在本身的電腦裏,曾經在團隊技術分享中分享過,現搬到線上來。ios
定義一個操做中的算法骨架,而將一些步驟延遲到子類中。TemplateMethod使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。git
(1) 一次性實現一個算法的不變部分,並將可變的信鴿網i留給子類來實現。github
(2) 各子類中公共的行爲應被提取出來並幾種到一個公共父類中以免代碼重複。算法
(3) 控制子類的擴展。設計模式
用模板方法實現遊戲的數據統計框架。遊戲每每有不少服,稱之爲大區,MMO遊戲中也稱之爲World。遊戲的數據統計會有不少數據指標,全部數據指標都既須要全局的統計,又須要各大區的分開統計,這些數據指標的統計邏輯統計方法又是徹底同樣的。咱們用模板方法定義一個適用於全部指標(活躍、流失、留存、付費等)的統計框架,具體統計邏輯留給子類實現。這樣的一個遊戲框架在2009年到2013年在行業第一的遊戲公司用在一百多款各種型遊戲數據統計上,固然,模板方法只是這個遊戲數據統計框架最基礎的一部分,一個通用的遊戲數據統計框架並無那麼簡單。網絡
Run()爲模板方法,Run()方法內固定依次調用ClusterInit()、Stat()、ClusterStat()。ClusterInit()完成統計初始化,Stat()完成各大區的分區統計,ClusterStat()完成全部大區結果去重統計。整個統計框架實現多線程調度,但具體實現統計邏輯的子類並沒有須關注線程調度,甚至徹底不懂線程的開發人員也能使用該統計框架開發出多線程統計程序。Run()模板方法確保了ClusterInit()只會在第一個進入統計邏輯的線程執行且只執行一次(此時,其餘線程處於等待ClusterInit()完成的阻塞狀態);Stat()方法在每一個線程中同時開始執行;ClusterStat()只在最後一個完成Stat()的線程執行且只執行一次。統計邏輯開發者只需專一於這三個方法的具體實現,其餘都交給框架完成,而框架則是經過者三個方法將骨架定義好,確保全部統計都按固定流程走。多線程
代碼實現:框架
AbstractClass.h:異步
#ifndef ABSTRACTCLASS_H_ #define ABSTRACTCLASS_H_ #include <iostream> using namespace std; class CAbstractClass { public: CAbstractClass(); virtual ~CAbstractClass(); int Run(); protected: virtual int Stat() = 0; virtual int ClusterInit() { return 0; } virtual int ClusterStat() { return 0; } int GetWorldId() { cout << "1" << endl; return 1; } }; #endif /* ABSTRACTCLASS_H_ */
AbstractClass.cpp:性能
#include "AbstractClass.h" CAbstractClass::CAbstractClass() { // TODO Auto-generated constructor stub cout << "abstract class construct" << endl; } CAbstractClass::~CAbstractClass() { // TODO Auto-generated destructor stub cout << "abstract class destruct" << endl; } int CAbstractClass::Run() { ClusterInit(); Stat(); ClusterStat(); return 0; }
ConcreteClass.h:
#ifndef CONCRETECLASS_H_ #define CONCRETECLASS_H_ #include "AbstractClass.h" class CConcreteClass : public CAbstractClass { public: CConcreteClass(); virtual ~CConcreteClass(); /* virtual int Run() { Stat(); ClusterInit(); ClusterStat(); } */ protected: virtual int Stat(); virtual int ClusterInit() { cout << "CConcreteClass ClusterInit()" << endl; } virtual int ClusterStat() { cout << "CConcreteClass ClusterStat()" << endl; } }; #endif /* CONCRETECLASS_H_ */
ConcreteClass.cpp:
#include "ConcreteClass.h" CConcreteClass::CConcreteClass() { // TODO Auto-generated constructor stub cout << "concrete class construct" << endl; } CConcreteClass::~CConcreteClass() { // TODO Auto-generated destructor stub cout << "concrete class destruct" << endl; } int CConcreteClass::Stat() { cout << "ConcreteClass::Stat()" << endl; }
TemplateMethodMain.cpp:
#include <iostream> #include "AbstractClass.h" #include "ConcreteClass.h" using namespace std; int main() { CAbstractClass* pStat = new CConcreteClass(); //CConcreteClass* pStat = new CConcreteClass(); pStat->Run(); delete pStat; return 0; }
模板方法在高性能的C++異步通訊框架Nebula中也有普遍應用,Nebula框架的Actor中的Cmd、Step、Session都使用了模板方法。