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