模板方法模式

在GOF的《设计模式:可复用面向对象软件的基础》一书中对模板方法模式是这样说的:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的接口即可重定义改算法的某些特定步骤。

我结合我在实际开发项目中的一个例子来说说这个模板方法模式吧。我们曾经做过一款产品,这个产品类似于一个云端的文件管理客户端。对于这样的一个客户端,由于其云端的服务器有三种,而每一种服务器之间的通信方式和对外公开的接口都是不是一致的,这就需要实现的客户端要屏蔽云端服务器和接口的差异性,而提供统一的操作界面,所以在实现这个客户端的同时,我们实现了一个框架,一个对于服务器和接口是通用的框架,比如就拿文件下载来说说。我们的实现大概如下:

class FileOperation
{
public:
bool DownloadFile(wchar_t *pSrc, wchar_t *pDest)
{
if (!pSrc || !pDest) return false;
if (!DoBeginDownloadFile(pSrc, pDest)) return false;
if (!DoDownloadFile(pSrc, pDest)) return false;
if (!DoEndDownloadFile(pSrc, pDest)) return false;
} protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
}; class HttpFileOperation : public FileOperation
{
protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
}; class SOAPFileOperation : public FileOperation
{
protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest);
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest);
};

下载文件的流程为:先调用DoBeginDownloadFile,执行下载文件之前的一些操作,再调用DoDownloadFile实现真正的文件下载,最后调用DoEndDownloadFile完成文件下载的清理工作。对于任何服务器,下载文件的这个流程是不会发生变化的。而在DoBeginDownloadFile、DoDownloadFile和DoEndDownloadFile的内部具体是如何实现的,由程序员根据具体的云端服务器和对外公开的接口来完成的。最终客户端去完成文件下载操作时,只会调用DownloadFile函数就可以完成。可以看到,在上面的代码中,只有DownloadFile是public的,其它的操作函数都是protected。这也意味着,我们完成的框架对外只公开DownloadFile接口。

UML类图

AbstractClass(抽象类):定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各步骤。主要是实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
ConcreteClass(具体类):实现原语操作以完成算法中与特定子类相关的步骤。
由于在具体的子类ConcreteClass中重定义了实现一个算法的各步骤,而对于不变的算法流程则在AbstractClass的TemplateMethod中完成。

使用场合

模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。在使用模板方法时,很重要的一点是模板方法应该指明哪些操作是可以被重定义的,以及哪些是必须被重定义的。要有效的重用一个抽象类,子类编写者必须明确了解哪些操作是设计为有待重定义的。

代码实现

这里就根据上面的类图,对模板方法模式进行了简单的实现。由于该模式非常简单,所以也没有更多的可以讲的了。

 #include <iostream>
using namespace std; class AbstractClass
{
public:
void TemplateMethod()
{
PrimitiveOperation1();
cout<<"TemplateMethod"<<endl;
PrimitiveOperation2();
} protected:
virtual void PrimitiveOperation1()
{
cout<<"Default Operation1"<<endl;
} virtual void PrimitiveOperation2()
{
cout<<"Default Operation2"<<endl;
}
}; class ConcreteClassA : public AbstractClass
{
protected:
virtual void PrimitiveOperation1()
{
cout<<"ConcreteA Operation1"<<endl;
} virtual void PrimitiveOperation2()
{
cout<<"ConcreteA Operation2"<<endl;
}
}; class ConcreteClassB : public AbstractClass
{
protected:
virtual void PrimitiveOperation1()
{
cout<<"ConcreteB Operation1"<<endl;
} virtual void PrimitiveOperation2()
{
cout<<"ConcreteB Operation2"<<endl;
}
}; int main()
{
AbstractClass *pAbstractA = new ConcreteClassA;
pAbstractA->TemplateMethod(); AbstractClass *pAbstractB = new ConcreteClassB;
pAbstractB->TemplateMethod(); if (pAbstractA) delete pAbstractA;
if (pAbstractB) delete pAbstractB;
}

总结

模板方法模式,总的来说很好接受,很好理解,没有难点;对于此设计模式,我个人觉的还是可以和装饰模式进行对比一下。还是有一些相似之处的。好了,该设计模式的讲解就到此结束。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  8. 设计模式-模板方法模式(Head First)

    参考书籍:Head First设计模式 什么是模板方法模式 定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 怎 ...

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

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

随机推荐

  1. springboot项目利用Swagger2生成在线接口文档

    Swagger简介. Swagger2是一款restful接口文档在线生成和在线调试工具.很多项目团队利用Swagger自动生成接口文档,保证接口文档和代码同步更新.在线调试.简单地说,你可以利用这个 ...

  2. 周末学习笔记——day01(函数,函数对象,嵌套调用,名称空间,作用域,闭包,装饰器)

    一,复习 字符编码 文件头:py2—ASCII,py3—UTF-8 三种字符串:u' ' b ' ' r ' ' u' ' .endcode(' utf-8 ') b' '.deconde(' utf ...

  3. 证明与计算(4): 完美散列函数(Perfect Hash function)

    原文:wiki: 完美散列函数 假设,写一个SQL语句解析器,词法分析对SQL语句解析,把语句分成了多个token,一般这个时候会需要查询这个token是否是一个关键字token. 例如keyword ...

  4. [转帖]Ansible批量远程管理Windows主机(部署与配置)

    2018-09-12 12:04:42 https://blog.51cto.com/7424593/2174156 一.测试环境介绍 Ansible管理主机: 系统:   CentOS6.8 IP ...

  5. 微信小程序开发编程手记20190303

    三元表达式: 运算: 引号与花括号之间如果有空格,将被视为字符串: pages页面容器标签: vscode:

  6. Hadoop Mapreduce分区、分组、二次排序

    1.MapReduce中数据流动   (1)最简单的过程:  map - reduce   (2)定制了partitioner以将map的结果送往指定reducer的过程: map - partiti ...

  7. 好用的UI设计工具

    51yuansu  好用的在线画UI图工具    51yuansu.com processon.com processon在线画图工具,程序流程图及UI设计原型图,脑图等 draw.io的PC版画图工 ...

  8. 查看Android系统已安装应用的列表

    可以通过adb shell pm list package 我们可以通过系统提供的工具pm来隐藏一些应用,比如:pm hide和pm disable pm disable <PACKAGE_OR ...

  9. H5与APP混合开发相关知识点总结

    整理一: 现在有这么个需求,如下图 app端点击右上角的 加 号 ,弹出模态框 这个项目是基于vue写的,客户端需要调用H5页面里定义的js方法,但是在vue里,所有的方法都是在组件内部声明的,也只能 ...

  10. JavaScript中大数相加的解法

    一.两个大正整数字符串相加 在JavaScript中,数值类型满足不了大数据容量计算,可以用字符串进行操作 function add(strNum1, strNum2) { // 将传进来的数字/数字 ...