1、模板方法模式概述:
模板方法模式(Template Method Pattern)是一种行为型设计模式,它在一个抽象类中定义了一个算法的骨架,将一些具体的步骤延迟到子类中实现。这样,子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。模板方法模式通过将相同的处理逻辑抽象到父类中,实现了代码复用和解耦。
2、模板方法模式的适用场景:
- 当多个子类有相似的处理逻辑,且逻辑执行顺序固定时,可以使用模板方法模式将公共逻辑抽取到父类中。
- 当你希望为算法提供一些可扩展点以便子类能够在不修改算法结构的情况下修改部分行为时。
- 当需要控制子类的扩展,使其仅能在特定点进行扩展时。
3、模板方法模式的优点:
- 代码复用:模板方法模式把相同的逻辑抽象到父类中,避免了子类中的重复代码。
- 解耦:模板方法模式将算法骨架和具体实现分离,使得子类可以在不改变算法结构的情况下重新定义某些特定步骤。
- 控制扩展:模板方法模式可以在特定点控制子类的扩展,使得算法的其他部分保持不变。
举例:
假设有一个制作蛋糕的应用程序,它有不同种类的蛋糕,但制作过程中某些步骤是相同的(如烘焙、冷却等)。使用模板方法模式,可以将这些公共步骤抽象到一个基类中,然后通过子类来实现各种蛋糕的特定步骤(如添加不同的配料和装饰)。
4、模板方法模式的缺点:
- 模板方法模式可能导致过多的类层次,因为每个子类都需要为算法的某个特定部分提供实现。
- 模板方法模式可能使得算法更难以理解,因为阅读算法的代码需要在多个类之间跳转。
举例:
在制作蛋糕的应用程序示例中,如果有很多种蛋糕,且每种蛋糕都有很多不同的变体,那么类层次可能会变得非常复杂。同时,要理解整个制个蛋糕的制作过程,需要在基类和子类之间进行跳转,这可能导致算法的理解变得困难。
5、用C++实现一个模板方法模式例子:
以下是一个C++实现的模板方法模式例子,这个例子展示了如何制作不同类型的蛋糕。
首先创建一个基类 Cake,定义制作蛋糕的基本步骤以及一个模板方法 makeCake:
#include <iostream>
class Cake {
public:
virtual ~Cake() = default;
void makeCake() {
prepareIngredients();
mixIngredients();
bake();
decorate();
}
protected:
virtual void prepareIngredients() = 0;
virtual void mixIngredients() = 0;
virtual void bake() = 0;
virtual void decorate() = 0;
};
接下来,创建两个子类,分别表示巧克力蛋糕和草莓蛋糕:
class ChocolateCake : public Cake {
protected:
void prepareIngredients() override {
std::cout << "Preparing chocolate cake ingredients..." << std::endl;
}
void mixIngredients() override {
std::cout << "Mixing chocolate cake ingredients..." << std::endl;
}
void bake() override {
std::cout << "Baking chocolate cake..." << std::endl;
}
void decorate() override {
std::cout << "Decorating chocolate cake..." << std::endl;
}
};
class StrawberryCake : public Cake {
protected:
void prepareIngredients() override {
std::cout << "Preparing strawberry cake ingredients..." << std::endl;
}
void mixIngredients() override {
std::cout << "Mixing strawberry cake ingredients..." << std::endl;
}
void bake() override {
std::cout << "Baking strawberry cake..." << std::endl;
}
void decorate() override {
std::cout << "Decorating strawberry cake..." << std::endl;
}
};
最后,在主函数中创建不同类型的蛋糕并制作:
int main() {
Cake *chocolateCake = new ChocolateCake();
Cake *strawberryCake = new StrawberryCake();
std::cout << "Making chocolate cake:" << std::endl;
chocolateCake->makeCake();
std::cout << std::endl << "Making strawberry cake:" << std::endl;
strawberryCake->makeCake();
delete chocolateCake;
delete strawberryCake;
return 0;
}
运行这个程序,输出如下:
Making chocolate cake:
Preparing chocolate cake ingredients...
Mixing chocolate cake ingredients...
Baking chocolate cake...
Decorating chocolate cake...
Making strawberry cake:
Preparing strawberry cake ingredients...
Mixing strawberry cake ingredients...
Baking strawberry cake...
Decorating strawberry cake...
在这个例子中,Cake 基类定义了制作蛋糕的基本步骤,而具体的蛋糕制作细节则在 ChocolateCake 和 StrawberryCake 子类中实现。这样可以确保所有类型的蛋糕都遵循相同的制作流程,同时允许子类自定义制作细节。