從零開始單排學設計模式「策略模式」黑鐵 II

孤獨鍵客發表於2019-02-15


閱讀本文大概需要 1.7 分鐘。

 

本篇是設計模式系列的第三篇,雖然之前也寫過相應的文章,但是因為種種原因後來斷掉了,而且發現之前寫的內容也很渣,不夠系統。所以現在打算重寫,加上距離現在也有一段時間了,也算是自己的一個回顧吧!

 

學而時習之,不亦說乎。

 

推薦閱讀:

從零開始單排學設計模式「UML類圖」定級賽

從零開始單排學設計模式「簡單工廠設計模式」黑鐵III

 

目前段位:黑鐵 II

 

 

Let's Go!

 

前言

 

設計模式不是語法,是一種巧妙的寫法,能把程式變的更加靈活。架構模式比設計模式大,架構模式是戰略,而設計模式是戰術。

 

設計模式分為3大型別:建立型,行為型,結構型,總共有23種。

 

策略模式

 

策略模式是對演算法的包裝,是把使用演算法的責任和演算法本身分割開來,委派給不同的物件管理。策略模式通常把一個系列的演算法包裝到一系列的策略類裡面,作為一個抽象策略類的子類。

 

用一句話來說,就是:“準備一組演算法,並將每一個演算法封裝起來,使得它們可以互換”。

 

在策略模式(Strategy Pattern)中,一個類的行為或其演算法可以在執行時更改。這種型別的設計模式屬於行為型模式。

 

設計原則有很多,這裡直說策略模式中使用到的,參看例項思考哪些地方有用到下面的設計模式: 
1. 封裝變化(找出應用中可能需要變化之處,把它們獨立出來,不要和哪些不需要變化的程式碼混在一起。) 
2. 針對介面,超類程式設計,而不是針對實現程式設計。 
3. 多用組合,少用繼承。

 

業務需求

 

如果讓你設計一個商場收銀軟體,營業員根據客戶所購買商品的單價和數量,向客戶收費。

 

程式碼實現

 

看到需求的你,對它進行了一個分析,只需要把數量乘以單價就可以得出總費用了,這可難不倒我,然後寫出了最初版本。

 

 

很簡單,直接宣告方法然後就計算出結算的總價了。

 

當你準備提交程式碼的時候,萬惡的產品找到你,給出了一個新版的需求。(暗地裡畫個圈圈咒詛產品...)

 

新的業務需求

 

如果讓你設計一個商場收銀軟體,營業員根據客戶所購買商品的單價和數量,向客戶收費。就是現在商場需要搞活動,會給顧客購買的商品進行打折,比如七五折,九五折等等。

 

程式碼實現

 

這不是計算完總價格之後,在後面乘以一下折扣就可以了。

 

經過改版,新的程式碼如下:

 

 

還沒有等你進行測試,產品就又找上門來了,我們可能後面會實現滿300送100、滿200送50....等等的很多活動,所以你程式需要設計靈活一點哈,不然到時候我的需求可以還會有變動的。

 

看到這裡,沒辦法,還是得繼續完善程式了,想偷個懶都沒有辦法,思考這種種得可能,你找尋這有沒有能完美貼切這種需求得處理方法。

 

打一折和打九折只是形式的不同,抽象分析出來,所有的打折演算法都是一樣的,所以打折演算法應該是一個類。冥思苦想下,你又寫出了第三版程式:

 

這裡抽離出來一個現金收費類,現金收取類的抽象方法,收取現金,引數為原價,返回當前價。

 

正常收費子類,正常收費,原價返回。

 

打折收費子類

 

返利收費子類

 

CashContext類,通過構造方法,傳入具體的收費策略。

客戶端主要程式碼

 

執行結果

 

現在就再也不怕了,如果再增加新的功能,只需要建立新的子類即可。

 

策略模式UML類圖

 

 

總結

 

意圖:定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。

 

主要解決:在有多種演算法相似的情況下,使用 if...else 所帶來的複雜和難以維護。

 

何時使用:一個系統有許多許多類,而區分它們的只是他們直接的行為。

 

如何解決:將這些演算法封裝成一個一個的類,任意地替換。

 

關鍵程式碼:實現同一個介面。

 

應用例項:

1、諸葛亮的錦囊妙計,每一個錦囊就是一個策略。

2、旅行的出遊方式,選擇騎自行車、坐汽車,每一種旅行方式都是一個策略。

3、JAVA AWT 中的 LayoutManager。

 

優點:

1、演算法可以自由切換。

2、避免使用多重條件判斷。

3、擴充套件性良好。

 

缺點:

1、策略類會增多。

2、所有策略類都需要對外暴露。

 

使用場景:

1、如果在一個系統裡面有許多類,它們之間的區別僅在於它們的行為,那麼使用策略模式可以動態地讓一個物件在許多行為中選擇一種行為。

2、一個系統需要動態地在幾種演算法中選擇一種。

3、如果一個物件有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。

 

注意事項:如果一個系統的策略多於四個,就需要考慮使用混合模式,解決策略類膨脹的問題。

 

 

 

往期精彩回顧

Bing掛了!百度又“贏了”

相關文章