目錄
- 策略模式
- 引例
- 動機 Motivation
- 模式定義
- 結構
- 要點總結
策略模式
引例
稅務計算系統,根據各個國家的稅法,進行稅務計算。各個國家稅法規定差別很大,需對應進行相應的實現。
- 常規解耦前寫法
使用if-else語句或switch-case語句進行結構化分而治之且有增加的擴展變化需求可能,擴展新的需求不方便。// 稅務類型 枚舉類型 enum TaxBase {CN_Tax,US_Tax,DE_Tax,// 擴展,更改變化點FR_Tax };class SalesOrder {TaxBase tax; public:double CalculateTax(){...if(tax == CN_Tax){// 中國稅務計算實現...}else if(tax == US_Tax){// 美國稅務計算實現}else if(tax == DE_Tax){// 德國稅務計算實現...}// 增加拓展法國,以下為更改變化點else if(tax = FR_Tax){// 法國稅務計算實現...} ...} };
以上違背“開閉原則”,即對擴展開發,對更改封閉
-
策略模式搭配簡單工廠寫法,代碼具有良好的本地性
// 稅法策略類 —— 基類 class TaxStrategy { public:virtual double Calculate(const Context& context) = 0;virtual ~TaxStrategy(){} }// 各稅法對應派生類 class CNTax : public TaxStrategy { public:virtual double Calculate(const Context& context){// 中國稅務計算實現...} };class USTax : public TaxStrategy { public:virtual double Calculate(const Context& context){// 美國稅務計算實現...} };class DETax : public TaxStrategy { public:virtual double Calculate(const Context& context){// 德國稅務計算實現...} };// 擴展變化點 class FRTax : public TaxStrategy { public:virtual double Calculate(const Context& context){// 法國稅務計算實現... } };// 以下部分穩定 class SalesOrder { private:// 多態的變量,一般使用指針TaxStrategy* strategy; public:// 工廠模式創建一個具體的稅務策略類SalesOrder(StrateFactory* strateFactory){this->strategy = strategyFactory->NewStrategy();}~SalesOrder(){delete this->strategy;}double CalculateTax(){...Context context();double val = strategy->Calculate(context); // 多態調用...} }
動機 Motivation
- 在軟件構建過程中,某些對象使用的算法可能多種多樣,經常改變,如果將這些算法都編碼到對象中,將會使對象變得異常復雜;有時支持不使用的算法也是一個性能負擔。
- 策略模式可以在運行時根據需要透明地更改對象的算法,將算法與對象本身解耦
模式定義
定義一系列算法,把它們一個個封裝起來,并且使它們可互相替換(變化)。該模式使得算法可獨立于使用它的客戶程序(穩定)而變化(擴展,子類化)。
結構
紅色部分為穩定部分,藍色部分為變化部分。
要點總結
- Strategy及其子類為組件提供了一系列可重用的算法,從而可以使
得類型在運行時方便地根據需要在各個算法之間進行切換。 - Strategy模式提供了用條件判斷語句以外的另一種選擇,消除條件
判斷語句,就是在解耦合。含有許多條件判斷語句的代碼通常都需
要Strategy模式。 - 如果Strategy對象沒有實例變量,那么各個上下文可以共享同一個
Strategy對象,從而節省對象開銷。
來源:極客班——C++設計模式入門