这是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. 移动APP外挂攻防实战

    前言 近日,某某龙在2018年的一次会议上发表了一个演讲,4000多人聚集在现场玩“跳一跳”游戏.随着他们指尖的翻飞跳跃,大屏幕上的现场排名也在不断刷新……而在全场的惊叹声中,最高分出现了,967分! ...

  2. Webview 浏览器开源项目总结

    在Android开发中,我们不免会遇到使用WebView实现网页展示的需求,以下是本人之前star的开源项目,供大家参考: 一.CrosswalkWebview 项目地址:https://github ...

  3. Javascript高级编程学习笔记(79)—— 表单(7)选择框脚本

    选择框脚本 选择框由<option>和<select>元素创建,为了方便选择框的交互,除了提供表单字段的公有方法之外 HTMLSelectElement 类型还提供下列特有的属 ...

  4. Java 11 究竟比 8 快了多少?

    阅读本文大概需要 1.2 分钟. 作者:h4cd 来源:开源中国社区 开源规划调度引擎 OptaPlanner 官网发布了一个 Java 11 GC 性能基准测试报告. 当前使用量最大的 Java 版 ...

  5. Java项目启动时执行指定方法的几种方式

    很多时候我们都会碰到需要在程序启动时去执行的方法,比如说去读取某个配置,预加载缓存,定时任务的初始化等.这里给出几种解决方案供大家参考. 1. 使用@PostConstruct注解 这个注解呢,可以在 ...

  6. Shiro基础

    Factory<T>接口(org.apache.shiro.util.Factory) 接口的getInstance()方法是泛型方法,可以用来创建SecurityManager接口对象 ...

  7. SpringMVC框架三:参数绑定

    这篇文章整合了SpringMVC和MyBatis: https://www.cnblogs.com/xuyiqing/p/9419144.html 接下来看看参数绑定: 默认Conrtroller可以 ...

  8. 【Spark调优】小表join大表数据倾斜解决方案

    [使用场景] 对RDD使用join类操作,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD或表的数据量比较小(例如几百MB或者1~2GB),比较适用此方案. [解决方案] ...

  9. Python - 使用Pylint检查分析代码

    1-简介 Home Page : https://www.pylint.org/ 检查语法错误,是否遵守编码风格标准.潜在的问题等: 支持自定义配置:例如显示或隐藏特定的警告,并且可以通过编写插件来添 ...

  10. 【app】adb连接问题整理

    如果使用adb devices进行检测,发现没有任何设备信息,我们就需要检查是否有手机/模拟器连接上 如果是手机进行连接,windows右下角有出来如下提示的话,需要检查你的手机驱动是否有安装好 如果 ...