Head First设计模式读书笔记一 策略模式
本文示例代碼材料源自Head First設計模式
以前整理自己整理的策略模式的鏈接:
https://blog.csdn.net/u011109881/article/details/60478840
策略模式思想
核心思想,分離變與不變。
例如原先我們設計了一個動物園系統,這個是個動物園是個不正經的動物園,只有鴨子,比如綠頭鴨,塑料玩具鴨,木頭鴨子等等。原先的系統已經設計好了,系統中有各種鴨子繼承了Duck,并有一個方法swim(假設所有鴨子都會游泳)
類圖如下:
要知道,作為程序員,肯定知道需求的變動是很頻繁的,現在發生了需求變動。要給原來的鴨子添加飛行的方法。有Java基礎的會立馬想到在Duck類中添加一個Fly方法。但是,請聽我說完需求。現在所需要的飛行方法不是單一的,比如綠頭鴨和野鴨等“真正的”鴨子是用翅膀飛的;木頭鴨,塑料玩具鴨是不能飛的。馬達鴨(一種玩具鴨,可以裝電池,利用馬達飛行)可以利用馬達飛行。這樣一來,繼承的方式就不太好了。如果硬要使用繼承,那么需要在每個子類鴨子重寫父類的fly方法。
那么,使用接口呢?比如寫出接口基類FlyBehavior。
然后用FlyNoWay接口表示不會飛的鴨子,FlyNoWay繼承了FlyBehavior,不會飛的鴨子實現FlyNoWay接口;
用FlyWithWings接口表示會用翅膀飛的鴨子,FlyWithWings繼承了FlyBehavior,會用翅膀飛的鴨子實現FlyWithWings接口;
以此類推。這樣乍看很好啊,沒有什么問題。但是很快我們會發現如果是木頭鴨和塑料鴨,它們都實現了FlyNoWay接口,并且都在自己的類中將該方法重寫一遍。因此,出現了重復代碼。
那么,還有其他什么更好的方式來添加飛行方法嗎?有,就是委托。委托這個詞看起來很難懂,但是我們可以把委托者和被委托者想成has-a(有一個)的關系。比如上面這個例子,鴨子(被委托者)有一個飛行行為(委托者)
把飛行想成Duck的一個功能,Duck具有該功能,即Duck本身含有飛行行為的實例,可以調用飛行行為的飛行方法。
詳細設計方式可以參見類圖
示例思路(規劃類圖)
類結構:
UML類圖:
實際代碼
- Duck基類
- 實體類MallardDuck
- 實體類ToyDuck
- 接口FlyBehavior
- 飛行實現類FlyNoWay
- 飛行實現類FlyWithWings
- 測試類
測試結果:
this is Tim--ToyDuck 這是個假的飛行方法,我根本不會飛 this is Jerry--mallardDuck 我用翅膀飛翔總結,再看實例
思路:分離變與不變。回憶之前的需求,可以發現,不變的是swim,變的是fly。雖然swim和fly都是鴨子的行為,但是swim不怎么變化,它可以利用繼承來實現代碼復用,而飛行方式卻有很多種,無法繼承,因此需要將飛行行為抽出來,各自實現,讓Duck實現類擁有飛行行為實例,達到操作飛行行為的目的。這種思想就像零件的組裝,主體是不變的,零件有各種相同功能不同性能的各種款式,這樣可以做出不同的產品。
另外策略模式還有一個好處是可以動態變化行為,比如木頭鴨子原來是不會飛的,它用setFlyBehavior設置不會飛行,后來設計師給他裝上了引擎翅膀,它可以再次通過setFlyBehavior在運行時動態變更飛行行為。
說到這里,回顧之前寫的策略模式(https://blog.csdn.net/u011109881/article/details/60478840)
在之前的例子中,看樣子類圖和本文的差很多,其實不然。我們對比一下:
Strategy就是本例中的FlyBehavior
Context就是本例中的Duck
之前的文章其實沒有本文的類結構復雜,因為前文“只有一種鴨子”,因此也就省去“鴨子的各種實現類了”,所以看上去是比較簡單的,但本質一樣。另外,個人覺得之前的文章例子雖然可以解釋策略模式,但是實際開發完全可以使用switch case來實現,因為那個例子沒有明顯的變與不變的地方。
其他策略模式的例子:
出行方式:比如一個角色character,他出門可以有不同的交通方式,如果目的地近,可以選擇步行,如果距離遠,可以選擇開車,如果路上塞車,可以選擇公交地鐵。那么出行方式的變化可以抽出來形成一種策略。拿本文中的例子類比的話,角色相當于鴨子,各種交通方式相當于飛行行為。
游戲角色和武器裝備:游戲中角色有不同的種類,戰士法師弓箭手盜賊等等,角色可以穿著不同的武器裝備,甚至還有角色限定,繼續類比,則角色相當于不同種類的鴨子,武器套裝則相當于不同的飛行方式,游戲角色可以隨時更換武器裝備。
總結
以上是生活随笔為你收集整理的Head First设计模式读书笔记一 策略模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(2458):素材管理
- 下一篇: 【书】Head First设计模式(中文