前言
在系统的设计开发过程中经常会遇到:对于某一个业务逻辑的算法实对于不同的对象中有着不同的内部细节实现,但是整体的逻辑运行框架是相同的。Template 提供了这种情况的一个实现框架。Template 模式采用继承的方式实现,其将逻辑框架放在抽象基类中,并定义好具体接口,然后在子类中实现具体运算细节。
一、模板模式(Template 模式)
Template 模式本质上还是利用多态的概念实现算法实现细节和高层接口的松耦合。可以看到 Template 模式采取的是继承方式实现这一点的,当然,继承也会给这种设计模式带来一些不方便的地方。UML图如下:
二、具体源码
1.Template.h
代码如下(示例):
#ifndef _TEMPLATE_H_
#define _TEMPLATE_H_
#include <iostream>
class AbstractClass
{
public:
virtual ~AbstractClass();
//定义算法内部实现,调用内部函数PrimitiveOperation1、PrimitiveOperation2
void TemplateMethod();
protected:
//纯虚函数,定义接口,设置为Protected,不提供对外接口
virtual void PrimitiveOperation1() = 0;
virtual void PrimitiveOperation2() = 0;
AbstractClass();
private:
};
class ConcreteClass1 :public AbstractClass
{
public:
ConcreteClass1();
~ConcreteClass1();
protected:
void PrimitiveOperation1();
void PrimitiveOperation2();
private:
};
class ConcreteClass2 :public AbstractClass
{
public:
ConcreteClass2();
~ConcreteClass2();
protected:
void PrimitiveOperation1();
void PrimitiveOperation2();
private:
};
#endif //_TEMPLATE_H_
2.Template.cpp
代码如下(示例):
#include "Template.h"
AbstractClass::AbstractClass()
{
}
AbstractClass::~AbstractClass()
{
}
void AbstractClass::TemplateMethod()
{
this->PrimitiveOperation1();
this->PrimitiveOperation2();
}
ConcreteClass1::ConcreteClass1()
{
}
ConcreteClass1::~ConcreteClass1()
{
}
void ConcreteClass1::PrimitiveOperation1()
{
std::cout << "ConcreteClass1...PrimitiveOperat ion1"<<std::endl;
}
void ConcreteClass1::PrimitiveOperation2()
{
std::cout << "ConcreteClass1...PrimitiveOperat ion2"<<std::endl;
}
ConcreteClass2::ConcreteClass2()
{
}
ConcreteClass2::~ConcreteClass2()
{
}
void ConcreteClass2::PrimitiveOperation1()
{
std::cout << "ConcreteClass2...PrimitiveOperat ion1"<<std::endl;
}
void ConcreteClass2::PrimitiveOperation2()
{
std::cout << "ConcreteClass2...PrimitiveOperat ion2"<<std::endl;
}
3.main.cpp
代码如下(示例):
#include "Template.h"
int main(int argc, char* argv[])
{
AbstractClass* p1 = new ConcreteClass1();
AbstractClass* p2 = new ConcreteClass2();
p1->TemplateMethod();
p2->TemplateMethod();
return 0;
}
三、运行结果
Template模式运行结果如下:
总结
Template 模式是很简单模式,也是应用很广的模式。具体而言,Template 采用继承的方式实现算法的异构,其关键点就是将通用算法封装在抽象基类中,并将不同的算法细节放到子类中实现。
Template 模式获得一种反向控制结构效果,这也是满足了面向对象系统的分析和设计中的依赖倒置原则。其含义就是父类调用子类的操作(高层模块调用低层模块的操作),低层模块实现高层模块声明的接口。这样控制权在父类(高层模块),低层模块反而要依赖高层模块。
继承的强制性约束关系也让 Template 模式有不足的地方,我们可以看到对于ConcreteClass 类中的实现的原语方法 Primitive1(),是不能被别的类复用。假设我们要创建一个 AbstractClass 的变体 AnotherAbstractClass,并且两者只是通用算法不一样,其原语操作想复用 AbstractClass 的子类的实现。但是这是不可能实现的,因为 ConcreteClass 继承自AbstractClass,也就继承了 AbstractClass 的通用算法,AnotherAbstractClass 是复用不了ConcreteClass 的实现,因为后者不是继承自前者。
Template 模式暴露的问题也正是继承所固有的问题,Strategy 模式则通过组合(委托)来达到和 Template 模式类似的效果,其代价就是空间和时间上的代价。
本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。