概念
模板模式(Template Method)也叫模板方法模式,属于行为型设计模式之一。它把具有特定步骤算法中的某些必要的处理委让给抽象方法。通过子类继承对抽象方法的不同实现改变整个算法的行为。
模板方法模式结构图
从结构图中我们可以看出父类(抽象类)除了提供给子类一套接口外还多了一个TemplateMethod()方法,这个方法也叫模板方法用于管理其他接口的调用顺序。也就是说,在抽象类中统一操作步骤,并规定好接口;让子类去实现这些规定好的接口。这样就可以把各个具体的子类和操作步骤解耦合(也就是说子类只负责实现抽象类规定好的这些接口,然后调用TemplateMethod(),不用去处理其它接口的调用顺序(因为在抽象类中已经在TemplateMethod()中处理了这一套流程的先后调用顺序))。
实例代码
#include <iostream>
using namespace std;
class MakeCar
{
public:
MakeCar() {}
virtual ~MakeCar() {}
virtual void makeHead() = 0;
virtual void makeBody() = 0;
virtual void makeTail() = 0;
//模板方法定义调用顺序
void make()
{
makeHead();
makeBody();
makeTail();
}
};
class Jeep : public MakeCar
{
public:
Jeep() {}
virtual ~Jeep() {}
virtual void makeHead()
{
cout<<"Make Jeep head~"<<endl;
}
virtual void makeBody()
{
cout<<"Make Jeep body~"<<endl;
}
virtual void makeTail()
{
cout<<"Make Jeep tail~"<<endl;
}
};
class SUV : public MakeCar
{
public:
SUV() {}
virtual ~SUV() {}
virtual void makeHead()
{
cout<<"Make SUV head~"<<endl;
}
virtual void makeBody()
{
cout<<"Make SUV body~"<<endl;
}
virtual void makeTail()
{
cout<<"Make SUV tail~"<<endl;
}
};
int main()
{
//面向抽象类编程 而不是 Jeep* car = new Jeep();(虽然这样也没毛病)
MakeCar* car = new Jeep();
car->make();
delete car;
cout<<"----------------"<<endl;
//面向抽象类编程 SUV* anotherCar = new SUV();(虽然这样也没毛病)
MakeCar* anotherCar = new SUV();
anotherCar->make();
delete anotherCar;
return 0;
}
代码中的make()方法充当模板方法,它规定了整个make car(造车)流程:先makeHead(),接着makeBody(),最后makeTail();子类Jeep和SUV分别实现了这些接口。最后在客户端调用的时候不同的子类也都是只调用make()模板方法即可完成这个造车流程,这也是模板方法的核心目的(实现具体子类和操作步骤解耦合)。
什么场景适用模板模式
1、具有统一的操作步骤或操作过程;
2、具有不同的操作细节;
3、存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同。
模板模式的优点
1、具体细节步骤实现定义在子类中,子类定义的详细处理算法是不会改变算法(流程)的整体架构;
2、代码复用的基本技术,在数据库设计中尤为重要;
3、存在一种反向的控制结构,通过一个父类调用其子类的操作,通过子类对父类进行扩展增加新的行为,符合“开闭原则”;
模板模式的不足
每个不同的实现都要定义一个新的子类,会导致类的个数增加,系统变得庞大。