設計模式入門 -- 策略模式

模擬鴨子游戲的需求

SimUDuck
游戲中會出現(xiàn)各種鴨子莱坎,一邊游泳戲水玫氢,一邊呱呱叫。
通過標準的OO技術讲仰,設計一個超類慕趴。

策略模式01

需求增加

此程序需要會飛 的鴨子競爭者拋在后頭

方法一:在 Duck 超類加上 fly() 方法

但問題發(fā)生了:并非 Duck 所有的子類都會飛(玩具鴨子)

注意:當涉及到維護是,為了“復用”(reuse)目的而使用繼承鄙陡,結局并不完美

方法二:覆蓋超類的方法

當有新的鴨子出現(xiàn)冕房,要檢查每個鴨子可能要覆蓋 fly() 和 quark() ...

  • 利用繼承來提供行為,導致的缺點
    1. 代碼在多個子類中重復
    2. 運行時的行為不容易改變
    3. 很難知道所有鴨子的全部行為
    4. 改變引發(fā)全身趁矾,造成其他鴨子不想要的改變

方法三:利用接口

可以把 fly() 從超類中提取出來耙册,放進一個“Flyable接口”中。這么一來毫捣,只有會飛的鴨子才實現(xiàn)此接口详拙。
看似不錯(只適應用不多,且飛的方式不同的情況)蔓同,但是在會飛的鴨子種類很多后饶辙,要稍微修改一下飛行的行為,就是一個災難...

分析

  1. 不是所有的子類都具有飛行和呱呱叫的行為斑粱,所以繼承不合適弃揽。
  2. 雖然 Flyable 和 Quackable 可以解決“一部分”問題,但是卻造成代碼無法復用,這只是從一個坑進入另一個坑矿微。
  3. 甚至痕慢,在會飛的鴨子中,飛行動作可能還有多種變化涌矢。掖举。。

解決之道--“采用良好的OO軟件設計原則”

軟件開發(fā)的一個不變的真理 --> 需求和改變

第一個設計原則:找出應用中可能需要變化之處娜庇,把它們獨立出來拇泛,不要和那些不需要變化的代碼混在一起
把會變化的部分取出來并“封裝”起來,好讓其它部分不會受到影響

為了把這兩個行為從Duck 類中分開思灌,將它們從 Duck 類中取出來俺叭,建立一組新類來代表每個行為。

設計鴨子的行為

讓鴨子類中的行為可以動態(tài)的改變就好了泰偿。我們應該在鴨子類中包含設定行為的方法熄守,這樣就可以在“運行時”動態(tài)的“改變”飛行行為。

第二個設計原則:針對接口編程耗跛,而不是針對實現(xiàn)編程
針對超類型編程

利用接口代表每個行為裕照,比方說 FiyBehavior 和 QuackBehavior ,而行為的每個實現(xiàn)都將實現(xiàn)其中的一個接口调塌。由行為類而不是Duck類來實現(xiàn)接口晋南。


  • 以前的做法:行為來自 Duck 超類的具體實現(xiàn),或是繼承某個接口并由子類自行實現(xiàn)而來羔砾。都依賴于“實現(xiàn)”负间,被實現(xiàn)綁的死死的,沒辦法更改行為(除非寫更多代碼)姜凄。

vs

  • 新設計中:鴨子的子類將使用接口(FlyBehavior 與 QuackBehavior)所標示的行為政溃,實際的“實現(xiàn)”不會被綁死在鴨子的子類中。即特定的具體行為編寫在實現(xiàn)了FlyBehavior 與 QuackBehavior 的子類中态秧。

策略模式02

這樣的設計董虱,可以放飛行和呱呱叫的動作被其他的對象復用,因為這些行為已經(jīng)與鴨子類無關了申鱼。
而我們可以新增一些行為愤诱,不會影響到既有的行為類,也不會影響“使用”到飛行行為的鴨子類捐友。

整合鴨子的行為

關鍵在于:鴨子現(xiàn)在會將飛行和呱呱叫的動作“委托”(delegate)別人處理淫半,而不是使用定義在 Duck 類(或子類)內(nèi)的呱呱叫和飛行方法。
做法:

  1. 首先楚殿,在 Duck 類中加入“兩個實例變量”撮慨,分別為“flyBehavior”與“quackBehavior”,聲明為接口類型(而不是具體類實現(xiàn)類型)脆粥,每個鴨子的對象都會動態(tài)地設置這些變量以在運行時引用正確的行為類型砌溺。
策略模式02
  1. 實現(xiàn) performQuack();
public class Duck{
    QuackBehavior quackBehavior变隔;
    // 還有更多
    public void performQuack(){
        quackBehavior.quack()规伐;//鴨子對象不親自處理呱呱叫行為,而是委托給quackBehavior引用的對象匣缘。
    }
}
  1. 如何設定 flyBehavior 與 quackBehavior的實例變量
public class MallardDuck extends Duck{
    public MallardDuck(){
        quackBehavior = new  Quack()猖闪;
        flyBehavior = new FlyWithWings();
    }
    //別忘了,因為 MallarDuck 繼承了 Duck 類肌厨,所以具有 flyBehavior 與 quackBehavior 實例變量
}

我們正在構造器里面制造了具體的Quack實現(xiàn)類的實例(在后面的模式中培慌,可以修正這一點)

動態(tài)設定行為

通過 set 方法來設定鴨子的行為,而不是在鴨子的構造器內(nèi)實例化柑爸。
Duck 類中 加入 setFlyBehavior(FlyBehavior fly)吵护;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市表鳍,隨后出現(xiàn)的幾起案子馅而,更是在濱河造成了極大的恐慌,老刑警劉巖譬圣,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓮恭,死亡現(xiàn)場離奇詭異,居然都是意外死亡厘熟,警方通過查閱死者的電腦和手機屯蹦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绳姨,“玉大人颇玷,你說我怎么就攤上這事【屠拢” “怎么了帖渠?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長竭宰。 經(jīng)常有香客問我空郊,道長,這世上最難降的妖魔是什么切揭? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任狞甚,我火速辦了婚禮,結果婚禮上廓旬,老公的妹妹穿的比我還像新娘哼审。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布涩盾。 她就那樣靜靜地躺著十气,像睡著了一般。 火紅的嫁衣襯著肌膚如雪春霍。 梳的紋絲不亂的頭發(fā)上砸西,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音址儒,去河邊找鬼芹枷。 笑死,一個胖子當著我的面吹牛莲趣,可吹牛的內(nèi)容都是我干的鸳慈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喧伞,長吁一口氣:“原來是場噩夢啊……” “哼蝶涩!你這毒婦竟也來了?” 一聲冷哼從身側響起絮识,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绿聘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后次舌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熄攘,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年彼念,在試婚紗的時候發(fā)現(xiàn)自己被綠了挪圾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逐沙,死狀恐怖哲思,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吩案,我是刑警寧澤棚赔,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站徘郭,受9級特大地震影響靠益,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜残揉,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一胧后、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抱环,春花似錦壳快、人聲如沸纸巷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘤旨。三九已至,卻和暖如春凛驮,著一層夾襖步出監(jiān)牢的瞬間裆站,已是汗流浹背条辟。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工黔夭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人羽嫡。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓本姥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親杭棵。 傳聞我的和親對象是個殘疾皇子婚惫,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

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