第一章 策略模式

1. 前言

設(shè)計模式的存在识啦,主要是方便代碼的可擴展性和提高代碼的復(fù)用性涕侈。在變化和穩(wěn)定之間尋找平衡點诈闺。

2. 從鴨子說起

策略模式菜枷,書中是以鴨子為例称鳞,進行介紹的涮较。
假設(shè)鴨子的父類為:

Duck
quack()
swim()
display()
//鴨子的其他方法
image.png

因 為 每 一 種 鴨 子 的外 觀 都 不 同 , 所 以display()方法是抽象的,每個鴨子子類負責(zé)實現(xiàn)自己的display冈止。

3. 鴨子要飛了

現(xiàn)在需要給鴨子們法希,增加一個飛的動作
新的需求來了靶瘸,這時候我們要加入鴨子會飛的功能苫亦。鴨子本來有翅膀,沒問題怨咪,在超類里加入一個fly方法屋剑,讓所有的子類繼承就好了,

Duck
quack()
swim()
display()
fly() //新加入的飛行方法
//鴨子的其他方法

確實诗眨,所有的鴨子都會飛了唉匾,然而系統(tǒng)里還有一些橡皮鴨子,它們也會飛了匠楚,這是不符合常理的N”臁!芋簿!
我們忽略了一件事情峡懈,并不是所有子類都會飛,某些不會飛的也繼承了此方法与斤。

注意:對代碼所做的局部修改肪康,影響層面可不只是局部。
當涉及"維護"時撩穿,為了"復(fù)用"目的而使用繼承磷支,結(jié)局并不完美。

3.1 第一個解決辦法—子類覆蓋

我們可以把橡皮鴨中的fly方法覆蓋掉

RubberDuck
quack(){//吱吱叫}
display(){//橡皮鴨}
fly(){
  //覆蓋食寡,什么也不做
}

這樣好像確實解決了橡皮鴨的問題雾狈,但如果我們以后每次加入不會飛的鴨子,都要這樣檢查一遍抵皱,就失去了復(fù)用的意義了善榛。

3.2 第二個解決辦法---利用接口

我們可以把fly方法從超類中取出來,放進一個Flyable接口中叨叙,這樣一來锭弊,只有會飛的鴨子才實現(xiàn)此接口。
這樣會帶來很多重復(fù)代碼擂错。


4. 重新看待問題

現(xiàn)在我們知道使用繼承并不能很好地解決問題,因為鴨子的行為在子類里不斷地改變,并且讓所有的子類都有這些行為是不恰當?shù)摹?br> Flyable與Quackable接口一開始似乎還挺不錯,解決了問題(只有會飛的鴨子才繼承Flyable),但是Java接口不具有實現(xiàn)代碼,所以繼承接口無法達到代碼的復(fù)用味滞。這意味著: 無論何時你需要修改某個行為,你必須得往下追蹤并在每一個定義此行為的類中修改它,一不小心,可能會造成新的錯誤!

幸運的是,有一個設(shè)計原則,恰好適用于此狀況。

設(shè)計原則: 找出應(yīng)用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起

在變化和穩(wěn)定之間尋找平衡點剑鞍。
好,該是把鴨子的行為從Duck類中取出的時候了!


5. 重新設(shè)計鴨子

我們提取出兩組類昨凡,一個是fly,一個是quack蚁署,每一組類實現(xiàn)各自的動作便脊,可以指定特定類型的飛行行為給鴨子,讓它們動態(tài)的去改變就好了光戈。

設(shè)計原則:針對接口編程哪痰,而不是針對實現(xiàn)編程。

我們利用接口代表每個行為久妆,行為的每個實現(xiàn)都將實現(xiàn)其中的一個接口晌杰。

image.png

這么一來,有了繼承的“復(fù)用”好處,卻沒有繼承所帶來的包袱。


6. 實現(xiàn)鴨子行為

首先筷弦,在Duck類中“加入兩個實例變量”肋演,分別為“flyBehavior”與“quack Behavior”,聲明為接口類型(而不是具體類實現(xiàn)類型),每個鴨子對象都會動態(tài)地設(shè)置這些變量以在運行時引用正確的行為類型(例如:FlyWithWings烂琴、Squeak等)爹殊。
我們也必須將Duck類與其所有子類中的fly()與quack()刪除,因為這些行為已經(jīng)被搬到FlyBehavior與QuackBehavior類中了。
我們用兩個相似的方法performFly()和performQuack()取代Duck類中的fly()與quack()奸绷。

//父類
Duck
FlyBehavior flyBehavior
QuackBehavior quackBehavior
performQuack(){      quackBehavior.quack();    }
swim()
display()
performFly()
//某個子類
public class MallardDuck extends Duck {    
     public MallardDuck() {       
          quackBehavior = new Quack();       
          flyBehavior = new FlyWithWings();
     }    

     public void display() {  
        System.out.println(“I’m a real Mallard duck”);    
    } 
}

7. 總結(jié)

當你將兩個類結(jié)合起來使用梗夸,如同本例一般,這就是組合(composition)健盒。這種做法和“繼承”不同的地方在于,鴨子的行為不是繼承來的绒瘦,而是和適當?shù)男袨閷ο蟆敖M合”來的。

如你所見扣癣,使用組合建立系統(tǒng)具有很大的彈性,不僅可將算法族封裝成類憨降,更可以“在運行時動態(tài)地改變行為”父虑,只要組合的行為對象符合正確的接口標準即可。

設(shè)計原則:多用組合授药,少用繼承士嚎。

策略模式
定義了算法族,分別封裝起來悔叽,讓它們之間可以互相替換莱衩,此模式讓算法的變化獨立于使用算法的客戶。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末娇澎,一起剝皮案震驚了整個濱河市笨蚁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖括细,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伪很,死亡現(xiàn)場離奇詭異,居然都是意外死亡奋单,警方通過查閱死者的電腦和手機锉试,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來览濒,“玉大人呆盖,你說我怎么就攤上這事〈眩” “怎么了絮短?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昨忆。 經(jīng)常有香客問我丁频,道長,這世上最難降的妖魔是什么邑贴? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任席里,我火速辦了婚禮,結(jié)果婚禮上拢驾,老公的妹妹穿的比我還像新娘奖磁。我一直安慰自己,他們只是感情好繁疤,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布咖为。 她就那樣靜靜地躺著,像睡著了一般稠腊。 火紅的嫁衣襯著肌膚如雪躁染。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天架忌,我揣著相機與錄音吞彤,去河邊找鬼。 笑死叹放,一個胖子當著我的面吹牛饰恕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播井仰,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼埋嵌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了俱恶?” 一聲冷哼從身側(cè)響起雹嗦,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤范舀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俐银,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尿背,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年捶惜,在試婚紗的時候發(fā)現(xiàn)自己被綠了田藐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吱七,死狀恐怖汽久,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踊餐,我是刑警寧澤景醇,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吝岭,受9級特大地震影響三痰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜窜管,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一散劫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幕帆,春花似錦获搏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至碱茁,卻和暖如春裸卫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背早芭。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工彼城, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人退个。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像调炬,于是被迫代替她去往敵國和親语盈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一代嗤、需求引入 鴨子有不同的種類:綠頭鴨、紅頭鴨缠借、橡皮鴨...干毅,它們都有相同點和不同點,相同點是它們都會游泳泼返,不...
    Javar閱讀 375評論 0 0
  • 一硝逢、先從簡單的模擬鴨子應(yīng)用做起 Joe上班的公司做了一套相當成功的模擬鴨子游戲。游戲中會出現(xiàn)各種鴨子绅喉,一邊游泳戲水...
    AC編程閱讀 21,673評論 3 11
  • 本文參照《Head First 設(shè)計模式》渠鸽,轉(zhuǎn)載請注明出處對于整個系列,我們按照這本書的設(shè)計邏輯柴罐,使用情景分析的方...
    詭異的葉子閱讀 613評論 0 5
  • 下雨了 這樣的夜晚注定難眠 翻開通訊錄 一連串的手機號 新的舊的 用的 不用的 每個手機里都有 上百個號碼 百分...
    孟冬廿六閱讀 152評論 0 1
  • 我有很多的心愿徽缚,我想要漂亮的容顏,想要富足的生活革屠,想要愉快的工作凿试,想要身體健康,想要孩子懂事聽話似芝,想要婚姻美...
    寶貝天空閱讀 376評論 0 0