这是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() = ; virtual int ClusterInit()
{
return ;
} virtual int ClusterStat()
{
return ;
} int GetWorldId()
{
cout << "" << endl;
return ;
}
}; #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 ;
}

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 ;
}

模板方法在高性能的C++异步通信框架Nebula中也有广泛应用,Nebula框架的Actor中的Cmd、Step、Session都使用了模板方法。

设计模式—模板方法的C++实现的更多相关文章

  1. javascript设计模式——模板方法模式

    前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...

  2. linkin大话设计模式--模板方法模式

    linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...

  3. 结合JDK源码看设计模式——模板方法模式

    前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...

  4. 瑞幸咖啡还是星巴克,一杯下午茶让我明白 设计模式--模板方法模式(Template Method Pattern)

    简介 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template M ...

  5. C#设计模式-模板方法模式

    提到模板,大家肯定不免想到生活中的“简历模板”.“论文模板”.“Word中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下 ...

  6. java设计模式 模板方法模式Template Method

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.毫无疑问,设计模式于己 ...

  7. Java设计模式--模板方法模式

    定义: 模板模式是一种行为设计模式,使用了JAVA的继承机制,在抽象类中定义一个模板方法,该方法引用了若干个抽象方法(由子类实现)或具体方法(子类可以覆盖重写).它的实现思路是,创建一个桩方法,并且定 ...

  8. JAVA 设计模式 模板方法模式

    定义 模板方法模式 (Template Method) 定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模 ...

  9. 深入浅出设计模式——模板方法模式(Template Method Pattern)

    模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...

  10. C#设计模式——模板方法(Template Method)

    一.概述在软件开发中,对某一项操作往往有固定的算法结构,而具体的子步骤会因为不同的需要而有所不同.如何可以在稳定算法结构的同时来灵活应对子步骤变化的需求呢?二.模板方法模板方法是一种常见的设计模式,它 ...

随机推荐

  1. JAVA RSA加密AES加密

    RSA加密: import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; imp ...

  2. Jenkins pipeline 并行执行任务流

    笔者在<Jenkins 在声明式 pipeline 中并行执行任务>一文中介绍了如何在声明式 pipeline 中执行并行的任务.前一段时间,Jenkins 发布了 1.3 版的声明式 p ...

  3. Nginx+tomcat集群使用redis共享session

    一 :nginx负载均衡 当Tomcat当做独立的Servlet容器来运行时,可看做是能运行Java Servlet的独立Web服务器. 此外 Tomcat还可以作为其他Web服务器进程内或者进程外的 ...

  4. Spark从入门到精通(一)

    什么是Spark 大数据计算框架 离线批处理 大数据体系架构图(Spark) Spark包含了大数据领域常见的各种计算框架:比如Spark Core用于离线计算,Spark SQL用于交互式查询,Sp ...

  5. JSP中的作用域

    application用于全局变量,可以获取全局的数据.作用范围比session大. JSP常用内置对象总结:out对象:用于客户端输出数据.request对象:用于处理客户端发送的请求的数据信息.r ...

  6. eslint prettier editrorconfig - 写出干净的前端代码

    FConfidence 关注 2018.12.30 02:38* 字数 2912 阅读 195评论 0喜欢 0 VSCode 插件安装 Prettier - Code Formatter ESLint ...

  7. angular整合环信webIM

    此处有两大坑: 1.下载easemob-websdk此npm包时,并没有下载strophe.js.crypto-js.underscore这三个包,需要自己手动下载. 2.如下方标红位置所示,需要自己 ...

  8. 【翻译】ES6生成器简介

    原文地址:http://davidwalsh.name/es6-generators ES6生成器全部文章: The Basics Of ES6 Generators Diving Deeper Wi ...

  9. Github page搭建博客使用自定义插件的方法

    Github page的后台程序是由Jekyll搭建,但由于Github的保护措施,非认证的plugin一般不会被Github page支持,但可以使用一些小技巧来绕过屏蔽. 以个人page为例,个人 ...

  10. springBoot(7)---整合Mybaties增删改查

    整合Mybaties增删改查 1.填写pom.xml <!-- mybatis依赖jar包 --> <dependency> <groupId>org.mybati ...