一.引入
二.template method(模板方法)
代码示例:
一开始的代码:
template1_app.cpp:
1 //应用程序开发人员
2 class Application{
3 public:
4 bool Step2(){
5 //...
6 }
7
8 void Step4(){
9 //...
10 }
11 };
12
13 int main()
14 {
15 Library lib; //这里都是以类的方式来调用方法的
16 Application app;
17
18 lib.Step1();
19
20 if (app.Step2()){
21 lib.Step3();
22 }
23
24 for (int i = 0; i < 4; i++){
25 app.Step4();
26 }
27
28 lib.Step5();
29
30 }
对应的库的代码:
template1_lib.cpp:
1 //程序库开发人员
2 class Library{
3
4 public:
5 void Step1(){
6 //...
7 }
8
9 void Step3(){
10 //...
11 }
12
13 void Step5(){
14 //...
15 }
16 };
这里的主体程序流程,实际上框架开发者已经设计好了,常常是稳定的.
因此更好的解决方案是,库开发者把流程写好,一些需要开发者实现的接口定义好,留给开发者实现:
改进后的代码:
template2_lib.cpp:
1 //程序库开发人员
2 class Library{
3 public:
4 //稳定 template method
5 void Run(){
6
7 Step1();
8
9 if (Step2()) { //支持变化 ==> 虚函数的多态调用
10 Step3();
11 }
12
13 for (int i = 0; i < 4; i++){
14 Step4(); //支持变化 ==> 虚函数的多态调用
15 }
16
17 Step5();
18
19 }
20 virtual ~Library(){ }
21
22 protected: //采用protected,让子类能够访问到.
23
24 void Step1() { //稳定
25 //.....
26 }
27 void Step3() {//稳定
28 //.....
29 }
30 void Step5() { //稳定
31 //.....
32 }
33
34 virtual bool Step2() = 0;//变化
35 virtual void Step4() =0; //变化
36 };
template2_app.cpp:
1 //应用程序开发人员
2 class Application : public Library {
3 protected:
4 virtual bool Step2(){
5 //... 子类重写实现
6 }
7
8 virtual void Step4() {
9 //... 子类重写实现
10 }
11 };
12
13
14
15
16 int main()
17 {
18 Library* pLib=new Application();
19 lib->Run();
20
21 delete pLib;
22 }
23 }
注意一下:
基类的析构函数要写成虚的,否则调用不到子类的析构函数,因为如果不是虚函数的话,
基类指针只能找到基类的析构函数,delete时只会调用基类的析构函数;而析构函数为虚函数时,则基类指针可以找到子类对应的析构函数.
红色部分时稳定的,蓝色部分是变化的.