標籤:c++ 設計模式 模板方法模式 策略模式
模板法模式:定義一個操作中的演算法骨架,而將一些步驟延遲到子類中。
按照《headfirst 設計模式》的例子,煮茶和煮咖啡的演算法架構(流程)是一樣的,只是有些演算法的實現是不一樣的,有些是一樣的。
我們可以將共同的演算法架構封裝為一個虛基類,將相同的演算法聲明為不可覆蓋的(static),不同的演算法聲明為子類要實現的純虛函數。
可以使用hook()函數處理演算法架構的細小差異。
看到這裡,或許會想起策略模式。策略模式也是將可以改變的演算法和不輕易改變的演算法區別對待,但策略模式和模板方法模式的最根本區別是:
策略模式是採用類組合,將不變的演算法仍保留在原來類中,只是將要重載的演算法單獨封裝為一個虛基類,子類實現自己的版本,這樣原來的類就
可以組合不同的介面子類,調用不同的演算法。
模板方法模式是採用類繼承,將演算法架構(步驟)封裝為一個虛基類,而且演算法架構是不可覆蓋的,子類只能對個別步驟有不同的實現。基類也可以引入hook()函數來對演算法架構微調。hook()鉤子函數的原理很簡單,基類的hook()函數可以定義為空白,也可以定義一些操作,子類可以對基類的hook()函數進行重載。
下面是不帶hook()鉤子的模板方法模式:
class CaffeineBeverage //咖啡因飲料{public: void PrepareRecipe() //咖啡因飲料沖泡法 { BoilWater(); //把水煮沸 Brew(); //沖泡 PourInCup(); //把咖啡因飲料倒進杯子 AddCondiments(); //加調料 } void BoilWater() {std::cout << "把水煮沸" << std::endl;} virtual void Brew() = 0; void PourInCup() {std::cout << "把咖啡倒進杯子" << std::endl;} virtual void AddCondiments() = 0;};class Coffee : public CaffeineBeverage{public: void Brew() {std::cout << "用沸水沖泡咖啡" << std::endl;} void AddCondiments() {std::cout << "加糖和牛奶" << std::endl;}};class Tea : public CaffeineBeverage{public: void Brew() {std::cout << "用沸水浸泡茶葉" << std::endl;} void AddCondiments() {std::cout << "加檸檬" << std::endl;}};int main(void){ std::cout << "沖杯咖啡:" << std::endl; Coffee c; c.PrepareRecipe(); std::cout << std::endl; std::cout << "沖杯茶:" << std::endl; Tea t; t.PrepareRecipe(); return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
[C++設計模式]template 模板方法模式