Skip to content

Commit 696c255

Browse files
authored
add template method pattern
1 parent 169eda7 commit 696c255

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Template Method Pattern
2+
3+
## 简介
4+
5+
属于**行为设计模式** - Behavioral Design Pattern。
6+
7+
!!! Abstract
8+
9+
常见的场景是当某种算法的整体步骤是固定的,但是某些步骤的实现可以有所不同或者可能会做定制化。
10+
11+
该算法本身是一个抽象类,定义了算法的骨架,而具体的实现则由其子类来完成。
12+
13+
比如,半导体测试设备的某个测试任务,通常包含加电DA转换,数据采集AD转换,数据后处理等步骤(当然还有状态机切换等复杂的任务,这里做了简化)。
14+
每个步骤都可以作为一个钩子(hook)接口对子类开放修改,而该测试任务对外的接口是固定的`DoTest()`
15+
16+
1. `protected` PreTest() - 准备测试 DA转换,外部不需要调用的接口
17+
2. `protected` DA_Conversion() - 纯虚函数,子类必须实现的接口
18+
3. `public` DoTest() - 执行测试 DA转换,加电,时序处理、中断标识处理、控制相机、控制光学仪器、采集数据、AD转换和数据后处理等,外部公开的接口
19+
4. `protected` AD_Conversion() - 纯虚函数,子类必须实现的接口
20+
5. `protected` PostTest() - 测试后处理 AD转换,外部不需要调用的接口
21+
22+
扩展场景来看,**代码生成**也符合这个特点。C#支持partial class机制,将类的文件拆分到多个文件中,最终编译时与生成代码合并。
23+
而这里的`Template`指的是class,而不是某个具体的method。
24+
25+
新建一个WinForm程序,我们可以看到这个Form类被拆成了两部分,一个是用户代码,另一个是设计器生成的代码。最终,它们会被合并成一个XXForm类,而开放给开发者修改的可以看成是一个钩子接口(这里是类包围的多个hook接口)。
26+
27+
!!! Abstract
28+
29+
以类为基本单元来看,我觉得继承本身就是一种模板方法模式,或者说模板方法的目的就是多态,而继承也是其实现机制之一。父类的接口是固定的,而子类可以重写父类的某些方法来实现不同的行为。
30+
31+
## Sample
32+
33+
```cpp
34+
#include <iostream>
35+
36+
using namespace std;
37+
38+
class Job
39+
{
40+
public:
41+
void Exec()
42+
{
43+
PreExec();
44+
DoJob();
45+
PostExec();
46+
}
47+
protected:
48+
virtual void PreExec() { cout << "++ Preparing Job" << endl; }
49+
virtual void DoJob() { /* ... */ }
50+
virtual void PostExec() { cout << "-- Job finishes!" << endl; }
51+
};
52+
53+
class AJob : public Job
54+
{
55+
protected:
56+
void DoJob() override { cout << "\tA Job running ..." << endl; }
57+
};
58+
59+
class BJob : public Job
60+
{
61+
protected:
62+
void DoJob() override { cout << "\tB Job running ..." << endl; }
63+
};
64+
65+
int main()
66+
{
67+
AJob job_a;
68+
BJob job_b;
69+
70+
Job& job1 = job_a;
71+
Job& job2 = job_b;
72+
73+
job1.Exec();
74+
job2.Exec();
75+
76+
return 0;
77+
}
78+
```
79+
80+
## Output
81+
82+
``` shell
83+
++ Preparing Job
84+
A Job running ...
85+
-- Job finishes!
86+
++ Preparing Job
87+
B Job running ...
88+
-- Job finishes!
89+
```

mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ nav:
124124
- C++:
125125
- Overview: c-cpp/cpp.md
126126
- iterator: c-cpp/iterator.md
127+
- Design Pattern:
128+
- Template Method: c-cpp/design_pattern/template_method.md
127129
- Build: c-cpp/build.md
128130
- Cross Compilation: c-cpp/cross-compile.md
129131
- GoogleTest: c-cpp/googletest.md

0 commit comments

Comments
 (0)