模板模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// TemplateMethod.h
#ifndef TEMPLATE_METHOD_H
#define TEMPLATE_METHOD_H

// 抽象基类,定义模板方法
class AbstractClass {
public:
virtual ~AbstractClass() = default;

// 模板方法,定义算法骨架
void templateMethod() {
stepOne();
stepTwo();
stepThree();
if (hookMethod()) {
stepFour();
}
}

protected:
// 基本方法 - 具体实现
void stepOne() {
std::cout << "AbstractClass: 执行步骤一" << std::endl;
}

// 基本方法 - 抽象方法,子类必须实现
virtual void stepTwo() = 0;

// 基本方法 - 具体实现
void stepThree() {
std::cout << "AbstractClass: 执行步骤三" << std::endl;
}

// 钩子方法 - 可以被子类重写,默认实现
virtual bool hookMethod() {
return true;
}

// 基本方法 - 抽象方法
virtual void stepFour() = 0;
};

// 具体子类A
class ConcreteClassA : public AbstractClass {
protected:
void stepTwo() override {
std::cout << "ConcreteClassA: 执行步骤二" << std::endl;
}

void stepFour() override {
std::cout << "ConcreteClassA: 执行步骤四" << std::endl;
}
};

// 具体子类B
class ConcreteClassB : public AbstractClass {
protected:
void stepTwo() override {
std::cout << "ConcreteClassB: 执行步骤二" << std::endl;
}

bool hookMethod() override {
// 重写钩子方法,改变算法流程
std::cout << "ConcreteClassB: 重写钩子方法,返回false" << std::endl;
return false;
}

void stepFour() override {
std::cout << "ConcreteClassB: 执行步骤四" << std::endl;
}
};

#endif // TEMPLATE_METHOD_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// main.cpp
#include <iostream>
#include "TemplateMethod.h"

int main() {
std::cout << "=== 使用 ConcreteClassA ===" << std::endl;
ConcreteClassA classA;
classA.templateMethod();

std::cout << "\n=== 使用 ConcreteClassB ===" << std::endl;
ConcreteClassB classB;
classB.templateMethod();

return 0;
}

这个模板模式的代码模板包含以下关键要素:

  1. AbstractClass - 抽象基类

    • templateMethod() - 模板方法,定义了算法的骨架
    • 具体方法 - 在基类中已实现的步骤(如 stepOne()stepThree()
    • 抽象方法 - 纯虚函数,必须由子类实现(如 stepTwo()stepFour()
    • 钩子方法 - 可以被子类重写的虚函数,提供算法的可选步骤(如 hookMethod()
  2. 具体子类 - ConcreteClassAConcreteClassB

    • 实现抽象方法以提供具体的行为
    • 可选择性地重写钩子方法以改变算法流程

这种设计模式的优势:

  • 封装不变部分,扩展可变部分
  • 提取公共代码,便于维护
  • 行为由父类控制,子类实现细节