这是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都使用了模板方法。