一、介绍
1.动机
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
2.定义
定义一个操作中的算法的骨架(稳定),而将一些步骤(变化)延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。——GOF
3.结构图
4.要点总结
Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
除了可以灵活应对步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method的典型应用。
在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。
二、模板模式
1.概念
模板模式用于创建一个通用的算法结构,其中一些步骤可以在子类中自定义,从而实现代码重用和扩展。
①模板模式的优点:
- 通过将不变部分的代码移至父类,子类只需要实现变化的部分,提高了代码复用。
- 新增具体类时,不需要改变抽象类和其他具体类的代码,保证了代码的可维护性和扩展性。
- 实现了反向控制(依赖倒置),即高层模块对低层模块的控制。
②模板模式的缺点:
- 每一个不同的实现都需要一个子类来实现,可能会导致系统中类的数目增加。
- 父类中的抽象方法由子类实现,子类的执行结果会影响到父类的结果,父类部分对子类产生了依赖性。
2.实现要点
- 模板类:模板类定义了算法的骨架,其中包含的模板方法的顺序不可改变。模板方法通常包括一些通用的算法步骤,它们可以是抽象方法,也可以是一些具体的方法。
- 具体类:具体类继承自模板类,并实现模板方法中的抽象步骤,以完成算法的具体逻辑。每个具体类可以实现不同的步骤,从而自定义算法的行为。
3.示例
//模板类
class TeaMaker {
public:
void makeTea() { //算法骨架
prepareTeaLeaves();
boilWater();
steepTea();
pourInCup();
addCondiments();
}
protected:
virtual void prepareTeaLeaves() = 0;
virtual void boilWater() = 0;
virtual void addCondiments() = 0;
void steepTea() {
cout << "Steeping the tea." << endl;
}
void pourInCup() {
cout << "Pouring tea into cup." << endl;
}
};
//具体类
class BlackTeaMaker :public TeaMaker {
protected:
virtual void prepareTeaLeaves() override {
cout << "Preparing black tea leaves." << endl;
}
virtual void boilWater() override {
cout << "Boiling the black tea." << endl;
}
virtual void addCondiments() override {
cout << "Adding sugar to black tea." << endl;
}
};
//具体类
class GreenTeaMaker :public TeaMaker {
protected:
virtual void prepareTeaLeaves() override {
cout << "Preparing green tea leaves." << endl;
}
virtual void boilWater() override {
cout << "Boiling the green tea." << endl;
}
virtual void addCondiments() override {
cout << "Adding lemon to green tea." << endl;
}
};
测试代码:
TeaMaker* blackTea = new BlackTeaMaker();
blackTea->makeTea();
delete blackTea;
cout << endl;
TeaMaker* greenTea = new GreenTeaMaker();
greenTea->makeTea();
delete greenTea;
输出结果:
Preparing black tea leaves.
Boiling the black tea.
Steeping the tea.
Pouring tea into cup.
Adding sugar to black tea.
Preparing green tea leaves.
Boiling the green tea.
Steeping the tea.
Pouring tea into cup.
Adding lemon to green tea.