類圖
為什么要將飛行和呱呱叫行為算法提取出來(lái)?
這些行為是容易變化的,將它們提取出來(lái)后續(xù)行為的具體實(shí)現(xiàn)方式發(fā)生變化不會(huì)對(duì)duck類產(chǎn)生任何影響拂蝎,只需要修改具體行為實(shí)現(xiàn)類自身的邏輯取胎。(即為封裝變化)
很多鴨子類型其實(shí)并不需要飛行挠进,如橡皮鴨边锁,死鴨子等矾麻,如果將飛行和叫行為放在duck父類中纱耻,所有的duck實(shí)現(xiàn)類都必須實(shí)現(xiàn)該方法,不需要該方法行為的鴨子在實(shí)現(xiàn)時(shí)就只能override該方法后空著不實(shí)現(xiàn)具體邏輯险耀,這樣會(huì)導(dǎo)致產(chǎn)生很多重復(fù)無(wú)用代碼弄喘。將這兩種行為作為duck的類變量,所有的飛行和呱呱叫都會(huì)委托具體行為去執(zhí)行甩牺,則可以清除這些無(wú)用代碼蘑志。(個(gè)人另外看法,對(duì)于無(wú)用代碼來(lái)說(shuō),可以把fly和quack方法座位duck類的普通方法急但,不要定義為抽象方法就可以了澎媒,不需要實(shí)現(xiàn)該方法的鴨子不要重寫該方法就好了)(組合代替繼承)
<b>個(gè)人看來(lái)最最最重要的一點(diǎn),也是策略模式的核心功能:運(yùn)行時(shí)可動(dòng)態(tài)改變行為策略</b>羊始,通過(guò)duck類暴露setter方法的方式旱幼,調(diào)用方可隨時(shí)根據(jù)需求更換duck類的行為策略,這也是在我看來(lái)<b>策略模式跟模版方法模式最大最大的區(qū)別</b>
策略模式在實(shí)際開(kāi)發(fā)中的應(yīng)用
首先突委,我在百度上搜到了好多展示自己如何運(yùn)用策略模式重構(gòu)自己代碼的例子柏卤,看完都發(fā)現(xiàn)其實(shí)完全不是那么回事,大多數(shù)案例都是以if else或者switch case這種代碼為切入點(diǎn)匀油,說(shuō)根據(jù)策略模式可以去掉這些難看的層層判斷缘缚,他們基本采用的方式是維護(hù)了一個(gè)map,客戶端調(diào)用時(shí)通過(guò)map找到對(duì)應(yīng)的策略敌蚜,然后執(zhí)行策略方法....從本質(zhì)上看這和if else沒(méi)有任何本質(zhì)的區(qū)別吧桥滨,只是把判斷具體用哪個(gè)策略的方法從if else改善成用map查找了而已。
個(gè)人覺(jué)得策略模式要想用好弛车,必須反映出運(yùn)行時(shí)動(dòng)態(tài)改變策略的能力齐媒。不然即使使用了策略模式,也就是模版方法模式的變種而已!!!
另外纷跛,關(guān)于運(yùn)行時(shí)動(dòng)態(tài)改變策略喻括,應(yīng)該是每一次改變是全局性的改變,只要改變了之后這個(gè)context類在下一次被修改策略前都要保持以現(xiàn)在的策略響應(yīng)請(qǐng)求贫奠。(就是說(shuō)改變不是臨時(shí)改變,唬血。。唤崭。不知道怎么形容)
在非單機(jī)的環(huán)境中拷恨,策略模式可能需要依靠消息中間件同步各服務(wù)器同時(shí)響應(yīng)策略修改,在分布式web開(kāi)發(fā)中谢肾,策略模式使用場(chǎng)景目前我狹隘的眼光看來(lái)還比較難用上腕侄,稍微可以想到的可能是一些容災(zāi)方案上面的,全局的策略變更也必須通過(guò)消息中間件或者分布式數(shù)據(jù)庫(kù)緩存等來(lái)實(shí)現(xiàn)芦疏,且要考慮一些容災(zāi)邏輯冕杠。
下面是自己想到的一些可以運(yùn)營(yíng)策略模式的場(chǎng)景:
- head first中提到的游戲中更換游戲角色的武器
- 實(shí)時(shí)翻譯程序中點(diǎn)擊切換語(yǔ)言按鈕時(shí)更換翻譯策略