一,模板方法模式的定义
模板方法模式是一种行为型设计模式,它先定义了一个算法的大致框架,然后将算法的具体实现步骤分解到多个子类中。
模板方法模式为算法设计了一个抽象的模板,算法的具体代码细节由子类来实现,从而使算法在整体上结构稳定,但是又能被灵活修改和扩展。
模板方法模式在现实生活中的抽象实例:
美食烹饪:烹饪包含很多步骤,包括选食材、切菜、煮熟等,但是每道菜的食材和烹饪时间会不同,此时可以将烹饪的通用步骤抽象为模板方法,具体细节由不同的菜来决定。
游戏开发:游戏中的角色有移动、攻击、防御等共同行为,将共同行为抽象为模板方法,具体细节根据不同的游戏角色来单独实现。
车辆生产:车辆生产流程中有组装、装配、涂漆等共同步骤,将共同步骤抽象为模板方法,具体的生产步骤根据不同的车型来改变。
例如:打工人作息模板
二,模板方法模式的结构
三,模板方法模式代码样例
#include <iostream>
class AbstractClass {
public:
//模板方法
void templateMethod() {
//算法步骤
execute1();
execute2();
}
protected:
//基本操作方法
virtual void execute1() = 0;
virtual void execute2() = 0;
};
class ConcreteClassA : public AbstractClass {
protected:
void execute1() override {
std::cout << "ConcreteClassA: execute1 called" << std::endl;
}
void execute2() override {
std::cout << "ConcreteClassA: execute2 called" << std::endl;
}
};
class ConcreteClassB : public AbstractClass {
protected:
void execute1() override {
std::cout << "ConcreteClassB: execute1 called" << std::endl;
}
void execute2() override {
std::cout << "ConcreteClassB: execute2 called" << std::endl;
}
};
int main() {
AbstractClass* classA = new ConcreteClassA();
classA->templateMethod();
AbstractClass* classB = new ConcreteClassB();
classB->templateMethod();
delete classA;
delete classB;
return 0;
}
运行结果:
ConcreteClassA: execute1 called
ConcreteClassA: execute2 called
ConcreteClassB: execute1 called
ConcreteClassB: execute2 called
四,模板方法模式的应用场景
软件框架开发:开发复杂的框架时先定义好基础流程,然后在子类中分别实现具体细节。
编译器开发:在编译器中先定义基本的步骤如词法分析、语法分析等,然后在子类中实现具体的解析步骤。
驱动程序开发:将程序的初始化、数据读写、通信等基础操作抽象为模板方法,然后根据不同的设备参数实现具体操作。
五,模板方法模式的优缺点
模板方法模式的优点:
使代码更加简洁,具体细节交给子类实现,避免了重复代码。
模板方法定义以后,后面只需要重点维护子类的代码实现,系统可扩展性和灵活性很强。
系统稳定性强,无论后续如何修改子类,算法的基本流程不变。
模板方法模式的缺点:
子类太多容易导致继承的过度滥用。
系统结构复杂,增加了代码维护难度。
如果有些基本操作没有提供默认的行为,可能导致功能出错。
六,代码实战
基于模板方法模式实现的模拟汽车生产
#include <iostream>
class VehicleTemplate {
public:
void buildVehicle() {
assembleBody();
installEngine();
addWheels();
std::cout<<"Vehicle is ready!\n";
}
virtual void assembleBody() = 0;
virtual void installEngine() = 0;
virtual void addWheels() = 0;
};
class Car: public VehicleTemplate {
public:
void assembleBody() override {
std::cout<<"Assembling car body.\n";
}
void installEngine() override {
std::cout<<"Installing car engine.\n";
}
void addWheels() override {
std::cout<<"Adding 4 wheels to the car.\n ";
}
};
class Motorcycle: public VehicleTemplate {
public:
void assembleBody() override {
std::cout<<"Assembling motorcycle frame.\n";
}
void installEngine() override {
std::cout<<"Installing motorcycle engine.\n";
}
void addWheels() override {
std::cout<<"Adding 2 wheels to the motorcycle.\n ";
}
};
int main() {
std::cout<<"Building a Car : \n";
Car car;
car.buildVehicle();
std::cout<<"\nBuilding a Motorcycle : \n";
Motorcycle motorcycle;
motorcycle.buildVehicle();
return 0;
}
运行结果:
Building a Car :
Assembling car body.
Installing car engine.
Adding 4 wheels to the car.
Vehicle is ready!
Building a Motorcycle :
Assembling motorcycle frame.
Installing motorcycle engine.
Adding 2 wheels to the motorcycle.
Vehicle is ready!
七,参考阅读
https://www.geeksforgeeks.org/template-method-design-pattern-c-design-patterns/
https://sourcemaking.com/design_patterns/template_method
https://www.geeksforgeeks.org/template-method-design-pattern/
https://www.modernescpp.com/index.php/the-template-method/