书中第三章介绍templated method 模版方法,
其核心思想是基类提供相同的运算框架,子类在相同框架基础上提供不同的实现。
python 实例如下:
1 #: c03:TemplateMethod.py
2 # Simple demonstration of Template Method.
3
4 class ApplicationFramework:
5 def __init__(self):
6 self.__templateMethod()
7 def __templateMethod(self):
8 for i in range(5):
9 self.customize1()
10 self.customize2()
11
12 # Create a "application":
13 class MyApp(ApplicationFramework):
14 def customize1(self):
15 print "Nudge, nudge, wink, wink! ",
16 def customize2(self):
17 print "Say no more, Say no more!"
18
19 # Create another "application":
20 class MyApp2(ApplicationFramework):
21 def customize1(self):
22 print "Basketball, basketball ",
23 def customize2(self):
24 print "Once more, Once more!"
25 MyApp()
26 MyApp2()
27 #<hr>
28 output = '''
29 Nudge, nudge, wink, wink! Say no more, Say no more!
30 Nudge, nudge, wink, wink! Say no more, Say no more!
31 Nudge, nudge, wink, wink! Say no more, Say no more!
32 Nudge, nudge, wink, wink! Say no more, Say no more!
33 Nudge, nudge, wink, wink! Say no more, Say no more!
34 Basketball, basketball Once more, Once more!
35 Basketball, basketball Once more, Once more!
36 Basketball, basketball Once more, Once more!
37 Basketball, basketball Once more, Once more!
38 Basketball, basketball Once more, Once more!
39 '''
2 # Simple demonstration of Template Method.
3
4 class ApplicationFramework:
5 def __init__(self):
6 self.__templateMethod()
7 def __templateMethod(self):
8 for i in range(5):
9 self.customize1()
10 self.customize2()
11
12 # Create a "application":
13 class MyApp(ApplicationFramework):
14 def customize1(self):
15 print "Nudge, nudge, wink, wink! ",
16 def customize2(self):
17 print "Say no more, Say no more!"
18
19 # Create another "application":
20 class MyApp2(ApplicationFramework):
21 def customize1(self):
22 print "Basketball, basketball ",
23 def customize2(self):
24 print "Once more, Once more!"
25 MyApp()
26 MyApp2()
27 #<hr>
28 output = '''
29 Nudge, nudge, wink, wink! Say no more, Say no more!
30 Nudge, nudge, wink, wink! Say no more, Say no more!
31 Nudge, nudge, wink, wink! Say no more, Say no more!
32 Nudge, nudge, wink, wink! Say no more, Say no more!
33 Nudge, nudge, wink, wink! Say no more, Say no more!
34 Basketball, basketball Once more, Once more!
35 Basketball, basketball Once more, Once more!
36 Basketball, basketball Once more, Once more!
37 Basketball, basketball Once more, Once more!
38 Basketball, basketball Once more, Once more!
39 '''
该方法的思想是基类提供一个框架模版,基类在构造函数中完成必要的初始化和启动引擎(templated mehtod),而用户,子类,只需要提供
customize1和customize2的具体实现即可。
2.templated method in c++
下面利用虚函数给出基本等价的c++实现,即customize1,customize2在基类中被定义程纯虚函数,
派生类负责提供具体实现,但在基类中可以调用customize1,同时c++的虚函数表机制保证了,在基类
中可以调用适当的派生类的实现(例如MyApp的对象会调用MyApp实现的customize1)
但是注意没有完全和上述python程序等价的c++实现,因为我们不能在构造函数中启动templated method,这是因为
基类的构造函数在构造的时候派生类对于C++编译器而言可以认为是还不存在的,在base class构造期间,virtual 函数
不是virtual函数,具体参见effective c++ 第三版的条款09 绝不在构造和析构过程中调用virtual 函数.
例如下面的C++代码,如果在构造函数中调用templateMethod()调则在运行时会出错显示试图调用pur virtual function,
即调用基类的customize1而基类的customize1仅仅是接口没有提供实现,所以会异常,退出。
1 #include <iostream>
2 using namespace std;
3
4 class ApplicationFramework {
5 public:
6 ApplicationFramework() {
7 //templateMethod();
8 }
9 void start() {
10 templateMethod();
11 }
12 virtual void customize1() = 0;
13 virtual void customize2() = 0;
14 virtual void customize3() {
15 cout << "base" << endl;
16 }
17 private:
18 void templateMethod() {
19 for (int i = 0; i < 5; i++) {
20 customize1();
21 customize2();
22 customize3();
23 }
24 }
25 };
26
27 class MyApp: public ApplicationFramework {
28 public:
29 void customize1() {
30 cout << "Nudge, nudge, wink, wink! ";
31 }
32 void customize2() {
33 cout << "Say no more, Say no more!" << endl;
34 }
35 void customize3() {
36 cout << "my app" << endl;
37 }
38 };
39
40 class MyApp2: public ApplicationFramework {
41 public:
42 void customize1() {
43 cout << "Basketball, basketball ";
44 }
45 void customize2() {
46 cout << "Once more, Once more!" << endl;
47 }
48 };
49
50 int main(int argc, char *argv[])
51 {
52 MyApp my_app = MyApp();
53 my_app.start();
54 MyApp2 my_app2 = MyApp2();
55 my_app2.start();
56 return 0;
57 }
58
59 /* output:
60 Nudge, nudge, wink, wink! Say no more, Say no more!
61 my app
62 Nudge, nudge, wink, wink! Say no more, Say no more!
63 my app
64 Nudge, nudge, wink, wink! Say no more, Say no more!
65 my app
66 Nudge, nudge, wink, wink! Say no more, Say no more!
67 my app
68 Nudge, nudge, wink, wink! Say no more, Say no more!
69 my app
70 Basketball, basketball Once more, Once more!
71 base
72 Basketball, basketball Once more, Once more!
73 base
74 Basketball, basketball Once more, Once more!
75 base
76 Basketball, basketball Once more, Once more!
77 base
78 Basketball, basketball Once more, Once more!
79 base
80 */
2 using namespace std;
3
4 class ApplicationFramework {
5 public:
6 ApplicationFramework() {
7 //templateMethod();
8 }
9 void start() {
10 templateMethod();
11 }
12 virtual void customize1() = 0;
13 virtual void customize2() = 0;
14 virtual void customize3() {
15 cout << "base" << endl;
16 }
17 private:
18 void templateMethod() {
19 for (int i = 0; i < 5; i++) {
20 customize1();
21 customize2();
22 customize3();
23 }
24 }
25 };
26
27 class MyApp: public ApplicationFramework {
28 public:
29 void customize1() {
30 cout << "Nudge, nudge, wink, wink! ";
31 }
32 void customize2() {
33 cout << "Say no more, Say no more!" << endl;
34 }
35 void customize3() {
36 cout << "my app" << endl;
37 }
38 };
39
40 class MyApp2: public ApplicationFramework {
41 public:
42 void customize1() {
43 cout << "Basketball, basketball ";
44 }
45 void customize2() {
46 cout << "Once more, Once more!" << endl;
47 }
48 };
49
50 int main(int argc, char *argv[])
51 {
52 MyApp my_app = MyApp();
53 my_app.start();
54 MyApp2 my_app2 = MyApp2();
55 my_app2.start();
56 return 0;
57 }
58
59 /* output:
60 Nudge, nudge, wink, wink! Say no more, Say no more!
61 my app
62 Nudge, nudge, wink, wink! Say no more, Say no more!
63 my app
64 Nudge, nudge, wink, wink! Say no more, Say no more!
65 my app
66 Nudge, nudge, wink, wink! Say no more, Say no more!
67 my app
68 Nudge, nudge, wink, wink! Say no more, Say no more!
69 my app
70 Basketball, basketball Once more, Once more!
71 base
72 Basketball, basketball Once more, Once more!
73 base
74 Basketball, basketball Once more, Once more!
75 base
76 Basketball, basketball Once more, Once more!
77 base
78 Basketball, basketball Once more, Once more!
79 base
80 */
综上,也证明了不考虑效率的化,显然python代码更优,因为你可以集中精力在问题上,而不用处处小心C++的陷阱,(如,my god 我又忽略了effective c++的条款...:))