C++设计模式:模板方法模式详解
在C++开发中,当面临相同执行流程但具体实现细节各异的业务场景时(如对接多种不同类型的云服务器),使用模板方法模式能有效提取公共逻辑。该模式定义了一个操作中的算法骨架,将一些步骤延迟到子类中重写,从而在不改变算法结构的前提下实现具体的差异化处理。
核心概念与适用场景
根据《设计模式:可复用面向对象软件的基础》定义,模板方法(Template Method)在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。这使得子类可以在不改变算法结构的情况下,重定义算法中的某些特定步骤。
这种模式是代码复用的基本技术,常用于以下情况:
- 多个子类有公有的行为,希望将它们提取到父类中避免代码重复。
- 通过钩子或虚函数控制子类的行为。
- 需要集中管理一个类中重要的算法或步骤。
实战案例:云端文件管理框架
假设我们正在开发一款多源接入的文件管理客户端,支持HTTP、SOAP等多种协议。尽管不同协议的底层通信方式差异巨大,但外部对用户的交互界面必须统一。此时,模板方法模式非常适合用来构建通用的后端框架。
第1步:定义通用抽象基类
首先定义一个抽象基类 FileOperation,公开统一的 DownloadFile 接口。该方法内部按固定顺序调用三个保护级的虚函数:
DoBeginDownloadFile:初始化连接等准备工作。DoDownloadFile:执行实际的数据传输。DoEndDownloadFile:关闭连接、释放资源等清理工作。
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;
return true;
}
protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest) = 0;
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest) = 0;
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest) = 0;
};
第2步:针对不同平台的具体实现
针对不同的服务器类型,继承基类并重写虚函数。例如 HTTP 和 SOAP 分别实现自己的逻辑:
// HTTP协议实现
class HttpFileOperation : public FileOperation
{
protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* HTTP开始逻辑 */ return true; }
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* HTTP下载逻辑 */ return true; }
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* HTTP清理逻辑 */ return true; }
};
// SOAP协议实现
class SOAPFileOperation : public FileOperation
{
protected:
virtual bool DoBeginDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* SOAP开始逻辑 */ return true; }
virtual bool DoDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* SOAP下载逻辑 */ return true; }
virtual bool DoEndDownloadFile(wchar_t *pSrc, wchar_t *pDest) override { /* SOAP清理逻辑 */ return true; }
};
这样,上层业务只需调用 DownloadFile 即可,无需关心底层是 HTTP 还是 SOAP。
标准 UML 类图解析
以下是模板方法模式的通用结构图:
图中包含两个核心角色:
- AbstractClass(抽象类):定义了
TemplateMethod(模板方法),其中封装了算法的执行顺序;同时声明了供子类重写的原语操作(Primitive Operation)。 - ConcreteClass(具体类):实现 AbstractClass 定义的抽象操作,以完成算法中与特定子类相关的步骤。
基础代码示例
为了清晰演示原理,以下是一个精简的控制台程序实现:
#include <iostream>
using namespace std;
class AbstractClass
{
public:
void TemplateMethod()
{
PrimitiveOperation1();
cout<<"TemplateMethod running..."<<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() override
{
cout<<"ConcreteA Implementation of Operation1"<<endl;
}
virtual void PrimitiveOperation2() override
{
cout<<"ConcreteA Implementation of Operation2"<<endl;
}
};
class ConcreteClassB : public AbstractClass
{
protected:
virtual void PrimitiveOperation1() override
{
cout<<"ConcreteB Implementation of Operation1"<<endl;
}
virtual void PrimitiveOperation2() override
{
cout<<"ConcreteB Implementation of Operation2"<<endl;
}
};
int main()
{
AbstractClass *a = new ConcreteClassA;
a->TemplateMethod();
delete a;
AbstractClass *b = new ConcreteClassB;
b->TemplateMethod();
delete b;
return 0;
}
总结
模板方法模式通过将“不变的部分”放在基类,“可变的部分”留给子类,极大地提高了代码的复用率和系统的可维护性。在实际工程中,建议在设计时明确区分哪些操作必须是固定的流程,哪些是需要被重定义的步骤。以上就是C++设计模式中模板方法模式的详细内容,更多关于软件开发与设计模式的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









