设计模式—模板方法的C++实现
这是Bwar在2009年写的设计模式C++实现,代码均可编译可运行,一直存在自己的电脑里,曾经在团队技术分享中分享过,现搬到线上来。
1. 模板方法简述
1.1 目的
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
1.2 适用性
(1) 一次性实现一个算法的不变部分,并将可变的信鸽网i留给子类来实现。
(2) 各子类中公共的行为应被提取出来并几种到一个公共父类中以避免代码重复。
(3) 控制子类的扩展。
2. 模板方法结构图
- AbstractClass:定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各步骤;实现一个模板方法,定义一个算法的股价。
- ConcreteClass:实现原语操作以完成算法中与特定子类相关的步骤。
3. 模板方法C++实现示例
用模板方法实现游戏的数据统计框架。游戏往往有很多服,称之为大区,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都使用了模板方法。
作者:Bwar 出处:https://www.cnblogs.com/bwar/
Bwar倾力打造的高性能网络框架Nebula:https://github.com/Bwar/Nebula
原创文章如转载,请注明出处。本文首发于博客园。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
几个Python小案例,爱上Python编程!
Python是一种面向对象的解释型编程语言,源代码与解释器CPython遵守GPL协议,Python语法简洁清晰。 语法简洁清晰,那么我们用少量的Python代码能做哪些有趣的东西?温馨提示:文末必看。 一、画爱心表白 1、图形都是由一系列的点(X,Y)构成的曲线,由于X,Y满足一定的关系,所以我们就可以建立模型,建立表达式expression,当满足时,两个for循环(for X in range;for Y in range)就会每行每列的打印。 2、Python代码与注释: 理清思路一行代码实现: 看上去是三行,在IDE中写作一行Python代码即可实现,如图: 此图为静态图,效果并不如意,那么我们把它做成动态图并实现图文表白如何?(可自行更改字母内容) 更改后代码如下: 二、快递查询工具 1、此Python小项目需要用到json与requests两个库,还需调用API。 2、代码注解: 3、查询效果: 三、Python爬虫入门级别教程之图片爬取 1、很多因为兴趣而学习Python的朋友大多是看到别人爬取视频、图片吧,我是以前看到别人爬取小电影,我才有动力学的。 2、Python...
- 下一篇
js代码与html代码分离示例
验证用户名是否存在的示例代码引出该思想: <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><metahttp-equiv="Content-Type"content="text/html;charset=UTF-8"><scripttype="text/javascript"src="${pageContext.request.contextPath}/js/myJS.js"></script><title>Inserttitlehere</title><scripttype="text/javascript">//方式一:使用文本框的onblu...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程