設計模式那點事--策略模式
概念:
策略模式定義了一系列的算法,分別封裝起來,讓它們之間能夠相互替換。
此模式讓算法的變化,不會影響到使用算法的客戶。策略,實質上指的是算法。
樣例:
一個鮮活簡單的樣例總能讓人輕松地理解晦澀的概念。
我們來看看一個關於汽車價格的策略模式。
我們知道。汽車的品牌和質量。決定了它的價格。
就像寶馬(BMW)。法拉利(Ferrali)和奔馳(Benz)三輛汽車,它們的價格肯定是不一樣的。那假設想要知道它的價格的話。能夠詢問銷售人員等等。可是在計算機裏,我們可不能直接問銷售人員啊!
對於它們來說。盡管各自價格不同。是不同的算法。可是獲取價格卻是一種公共操作(策略模式要求的就是要封裝變化的算法)。於是。能夠創建一個抽象父類汽車類(Car
然後創建三個子類:BMW,Ferrali和Benz,分別繼承於Car。通過繼承關系,每一個子類能夠改寫父類的GetPrice函數,然後在client中通過調用不同的汽車子類算法來獲取子類汽車價格。
總結一下:
1、我們把父類Car當成是抽象策略類,提供了一個獲取價格的GetPrice接口;
2、每種包括獲取價格GetPrice的汽車類為詳細策略類(每種牌子的車價格不一致,導致不同計算算法)。要重寫父類Car的GetPrice函數;
3、建立一個環境上下文類PriceContext,維護一個對父類
UML圖:
代碼:
#include <iostream> using namespace std; class Car { public: float m_fPrice; public: virtual float GetPrice() { return m_fPrice*1; } }; class BMW:public Car { public: float GetPrice() { return m_fPrice*3; } }; class Ferrali:public Car { public: float GetPrice() { return m_fPrice*11; } }; class Benz:public Car { public: float GetPrice() { return m_fPrice*6; } }; class PriceContext { public: int m_iFlag; private: Car* m_cCar; public: PriceContext(Car* cCar):m_cCar(cCar) { //this->m_cCar = cCar; } float GetPriceContext() { m_cCar->m_fPrice = 10000; return(m_cCar->GetPrice()); } }; int main() { float fPrice=0.0; int iTag=0; cout<<"----策略模式開始----"<<endl; cout<<"BMW:1,Ferrali:2,Benz:3"<<endl; cout<<"請輸入您想要查詢的汽車價格:"; cin>>iTag; PriceContext* priceContext; switch (iTag) { case 1: priceContext = new PriceContext(new BMW); break; case 2: priceContext = new PriceContext(new Ferrali); break; case 3: priceContext = new PriceContext(new Benz); break; default: priceContext = new PriceContext(new Car); break; } fPrice = priceContext->GetPriceContext(); delete priceContext; priceContext = NULL; cout<<"價格為:"<<fPrice<<endl; cout<<"----策略模式結束----"<<endl; return 1; }
策略模式和簡單工廠模式相結合:
簡單工廠模式中。對象的動態創建推斷放在了工廠類中。
而主要的策略模式client還是要進行算法推斷和對象創建。
因此可模仿簡單工廠,把算法的推斷移到環境上下文類中,盡量降低client職責,降低耦合性。當中相對簡單工廠模式來說,client中連基類都不出現,更加地隱藏算法的詳細實現細節。
代碼:
class PriceContext { public: int m_iFlag; private: Car* m_cCar; public: PriceContext(int iFlag) //構造中不再穿對象。傳標識 { switch (iFlag) { case 1: m_cCar = new BMW; break; case 2: m_cCar = new Ferrali; break; case 3: m_cCar = new Benz; break; default: m_cCar = new Car; break; } } float GetPriceContext() { m_cCar->m_fPrice = 10000; return(m_cCar->GetPrice()); } }; int main() { float fPrice=0.0; int iTag=0; cout<<"----策略模式開始----"<<endl; cout<<"BMW:1,Ferrali:2,Benz:3"<<endl; cout<<"請輸入您想要查詢的汽車價格:"; cin>>iTag; PriceContext* priceContext = new PriceContext(iTag); fPrice = priceContext->GetPriceContext(); delete priceContext; priceContext = NULL; cout<<"價格為:"<<fPrice<<endl; cout<<"----策略模式結束----"<<endl; return 1; }
總結:
1、策略模式定義了一系列的算法。從概念上看,全部算法完畢的都是同樣的操作,僅僅是表現行為不同。通過同樣的方式調用全部的算法(使用多態),降低了算法類與使用算法類之間的耦合。
2、對客戶隱藏詳細策略(算法)的實現細節,彼此全然獨立;
3、策略模式簡化了單元測試,每一個算法都有自己的類。能夠通過自己的接口單獨測試;
4、client必須知道全部的策略類,並自行決定使用哪一個策略類。這就意味著client必須理解這些算法的差別,以便適時選擇恰當的算法類。換言之,策略模式僅僅適用於client知道全部的算法或行為的情況。
設計模式那點事--策略模式