感謝Quark提供template版本的template method寫法
1#include <iOStream>
2
3using namespace std;
4
5template<typename T>
6class DrinkMachine {
7public:
8 void makeDrink() {
9 T* derived =(T*) this;
10
11 this->boilWater();
12 derived->doPutIngredIEnt();
13 derived->doPourInCup();
14 derived->doAddFlavoring();
15 }
16
17protected:
18 void boilWater() {
19 cout << "boil some water" << endl;
20 }
21};
22
23class TeaMachine : public DrinkMachine<TeaMachine> {
24frIEnd DrinkMachine<TeaMachine>;
25protected:
26 void doPutIngredIEnt() const { cout << "steep tea in boiling water" << endl; }
27 void doPourInCup() const { cout << "pour tea in cup" << endl; }
28 void doAddFlavoring() const {cout << "add lemon" << endl; }
29};
30
31class CoffeeMachine:public DrinkMachine<CoffeeMachine> {
32frIEnd DrinkMachine<CoffeeMachine>;
33protected:
34 void doPutIngredIEnt() const { cout << "brew coffee in boiling water" << endl; }
35 void doPourInCup() const { cout << "pour coffee in cup" << endl; }
36 void doAddFlavoring() const {cout << "add sugar and milk." << endl; }
37};
38
39int main() {
40 cout << "Making Tea" << endl;
41 DrinkMachine<TeaMachine> *pTeaMachine = &TeaMachine();
42 pTeaMachine->makeDrink();
43
44 cout << endl;
45
46 cout << "Making Coffee" << endl;
47 DrinkMachine<CoffeeMachine> *pCoffeeMachine = &CoffeeMachine();
48 pCoffeeMachine->makeDrink();
49}
50
Remark
strategy和template method目的相同,皆對『新需求』的不同演算法提供『擴充』的機制,但手法卻不同,strategy采用object的方式,利用delegation改變algorithm,而template method則采用class的繼承方式來改變algorithm,由於用到的是class的inheritance,所以在compile-time就已經決定要override的algorithm,run-time就無法再改了,但strategy用的是object手法,所以在run-time還可以透過換object改變algorithm。
GoF的原文如下
Template methods use inheritance to vary part of an algorithm. StrategIEs use delegation to vary the entire algorithm.