C++设计模式——模板方法模式
模板方法模式
在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++设计模式——模板方法模式的更多相关文章
- linkin大话设计模式--模板方法模式
linkin大话设计模式--模板方法模式 准备一个抽象类,将部分逻辑以具体方法的形式实现,然后申明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不 ...
- 结合JDK源码看设计模式——模板方法模式
前言: 相信很多人都听过一个问题:把大象关进冰箱门,需要几步? 第一,把冰箱门打开:第二,把大象放进去:第三,把冰箱门关上.我们可以看见,这个问题的答案回答的很有步骤.接下来我们介绍一种设计模式--模 ...
- 瑞幸咖啡还是星巴克,一杯下午茶让我明白 设计模式--模板方法模式(Template Method Pattern)
简介 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template M ...
- C#设计模式-模板方法模式
提到模板,大家肯定不免想到生活中的“简历模板”.“论文模板”.“Word中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下 ...
- java设计模式 模板方法模式Template Method
设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.毫无疑问,设计模式于己 ...
- JAVA 设计模式 模板方法模式
定义 模板方法模式 (Template Method) 定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模 ...
- 深入浅出设计模式——模板方法模式(Template Method Pattern)
模式动机 模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一.在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中.在模板方法模式 ...
- 设计模式-模板方法模式(Head First)
参考书籍:Head First设计模式 什么是模板方法模式 定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. 怎 ...
- javascript设计模式——模板方法模式
前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...
随机推荐
- 使用代码生成工具Database2Sharp快速生成工作流模块控制器和视图代码
在前面随笔<基于Metronic的Bootstrap开发框架--工作流模块功能介绍>和<基于Metronic的Bootstrap开发框架--工作流模块功能介绍(2)>中介绍了B ...
- TypeError: argument to reversed() must be a sequence ERROR basehttp 124 "GET /admin/ HTTP/1.1" 500 114103 Performing system checks...
Error Msg TypeError: argument to reversed() must be a sequence ERROR basehttp 124 "GET /admin/ ...
- springboot 学习进度
1 hello world --------------ok 主启动程序必须在层次结构的最上面. 2 配置 3.日志 4.Web开发 1)SpringBoot集成JSP的方法 配置applicatio ...
- swiper 轮播图,拖动之后继续轮播
在此贴出swiper官网地址:https://www.swiper.com.cn/api/index.html 示例如下(官网示例): <script> var mySwiper = ne ...
- 【数学建模】MatLab 数据读写方法汇总
1.读入 txt 文件数据. load xxx.txt A=load(‘xxx.txt’) A=dlmread(‘xxx.txt’) A=importdata(‘xxx.txt’) 例:将身高体重的 ...
- Django+Vue打造购物网站(九)
支付宝沙箱环境配置 https://openhome.alipay.com/platform/appDaily.htm?tab=info 使用支付宝账号进行登陆 RSA私钥及公钥生成 https:// ...
- L2-006 树的遍历 (25 分) (根据后序遍历与中序遍历建二叉树)
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456 L2-006 树的遍历 (25 分 ...
- maven 使用 log4j
Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件,甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进程等:我们也可 ...
- go实现json数组嵌套
go实现json数组嵌套 引用包 "encoding/json" 定义以下结构体 type person struct { Name string `json:"name ...
- IIS运行一段时间不响应的解决方法
查找事件记录,提示为应用程序池 'DefaultAppPool' 提供服务的进程关闭时间超过了限制 解决方案: Internet 信息服务(IIS)管理器->应用程序池->DefaultA ...