模板方法模式是一种行为设计模式,它通过定义一个算法的骨架,而将一些步骤延迟到子类中实现。Template Method 使得子类可以不改变(复用)一个算法结构 即可重定义(override 重写)该算法的某些特定步骤。
基本结构
// 抽象类定义模板方法和基本操作
class AbstractClass {
public:
// 模板方法,定义算法骨架(通常声明为final防止子类覆盖)
void templateMethod() const {
this->baseOperation1();
this->requiredOperation1();
this->baseOperation2();
this->requiredOperation2();
}
// 基类中已实现的操作
void baseOperation1() const {
std::cout << "AbstractClass: 执行基础操作1\n";
}
void baseOperation2() const {
std::cout << "AbstractClass: 执行基础操作2\n";
}
// 需要子类实现的纯虚函数
virtual void requiredOperation1() const = 0;
virtual void requiredOperation2() const = 0;
// 虚析构函数
virtual ~AbstractClass() = default;
};
开发人员只需继承AbstractClass 重写其中的虚函数然后调用templateMethod()即可
/ 具体实现类1
class ConcreteClass1 : public AbstractClass {
public:
void requiredOperation1() const override {
std::cout << "ConcreteClass1: 实现操作1\n";
}
void requiredOperation2() const override {
std::cout << "ConcreteClass1: 实现操作2\n";
}
};
// 具体实现类2(带钩子方法覆盖)
class ConcreteClass2 : public AbstractClass {
public:
void requiredOperation1() const override {
std::cout << "ConcreteClass2: 实现操作1\n";
}
void requiredOperation2() const override {
std::cout << "ConcreteClass2: 实现操作2\n";
}
void hook() const override {
std::cout << "ConcreteClass2: 覆盖钩子方法\n";
}
};
具体调用
int main() {
std::cout << "同一客户端代码可以处理不同子类:\n";
AbstractClass *concreteClass1 = new ConcreteClass1();
concreteClass1->templateMethod();
std::cout << "\n同一客户端代码可以处理不同子类:\n";
AbstractClass *concreteClass2 = new ConcreteClass2();
concreteClass2->templateMethod();
return 0;
}
uml图
应用场景
框架设计:定义框架的流程,允许用户自定义特定步骤
算法骨架固定:当多个类有相似算法但实现细节不同时
代码复用:将公共行为提取到父类中
控制子类扩展:限制子类只能修改算法的特定部分
优点
提高代码复用性,避免重复代码
良好的扩展性,符合开闭原则
便于维护,算法修改只需在父类中进行
反向控制结构,父类控制整体流程
缺点
每个不同的实现都需要一个子类,可能导致类数量增加
通过继承实现,可能违反组合优于继承的原则
父类与子类之间紧密耦合
实际应用示例
STL中的分配器(allocator):定义内存分配算法框架
GUI框架:如窗口显示流程固定,具体绘制由子类实现
单元测试框架:定义测试流程(setUp, test, tearDown)
编译器设计:编译流程固定,具体语法分析等步骤可变