說到策略模式,我們最早想到的就是商店的收銀方式:不滿100,正常收費;超過100不滿300,超過的部份打8折;超過300,全價9折!
解決這個問題最最普通的方法就是大量的If…Else…,而它帶來的就是無情的難以保護,每次條件變更都會修改原代碼,嚴重違背了開閉原則。
不言而喻,策略模式的解決方式就是封裝了1系列平行且復雜的實現方式,在不同的場景下,我們選擇1個最合適的方案。
來看它的類圖
圖⑴ 《大話設計模式》
圖⑵ 《HeadFirst》
第1張是《大話設計模式》里的,第2張是《HeadFirst》里的1個具體的例子。
第1個比較簡單,也最典型。不過量說了。
來看第2個,它實際上是經過了1系列演化的。原來的“飛行”接口是封裝在Duck里的,也就是說所有的鴨子都必須會飛才行。但實際上有的鴨子只能跑,那怎樣辦?就只能把“飛行”抽取出來,構成1個單獨的接口,讓會飛的鴨子去實現。
這樣還有問題,如果有的鴨子能直接飛,有的鴨子需要助跑飛,那怎樣辦?每一個類型的鴨子都需要重寫飛行方法,這樣也不適合,所以就寫出“飛行”接口實現的子類,再讓符合該類型的鴨子去調用。實質就是1種多態。
策略就體現在它封裝了不同的飛行方式,可供客戶端去選擇1個最好的、最適合的去調用。
狀態模式:當1個對象的內在狀態變化時允許改變起行動,這個對象看起來像是改變了其類。
來看它的類圖:
狀態模式主要突出了兩個字:“改變”,對象的狀態決定了狀態的行動,我們精神亢奮的時候,就努力的工作,努力的工作就致使了我們身心疲憊,身心疲憊就致使我們的行動是需要休息。從這里我們可以看出,事物的內在狀態決定了事物所做出的行動,而事物的行動又會改變我們事物的狀態,二者在不斷的相互影響,然后實現狀態的轉換。
狀態模式主要解決的是當控制1個對象狀態轉換的條件表達式過于復雜的情況。把狀態的判斷轉移到表示不同狀態的1系列類中,可以把復雜判斷簡化。
當1個狀態的行動取決于他的狀態,并且他必須在運行時刻根據狀態改變他的行動時,可以斟酌使用狀態模式。
比較:從上面這幾點,我們可以看出策略模式和狀態模式的利用場景有很大的不同:1個是封裝1系列平行且復雜多變的實現方式,1個是實現把對象的內在狀態的變化封裝起來,用外部行動來表現出來。
總之,雖然2者的類圖很相似,但實際上解決的是不同情況的兩種場景問題,需要我們去實際分析和判斷。不同設計模式之間存在不同的設計思路,相似的更需要我們去仔細比較,每次學習都是1次進步和再認識。