設(shè)計模式淺談 —— 策略模式

設(shè)計模式

開題先說明一下奥此,設(shè)計模式告訴我們?nèi)绾谓M織類和對象以解決某種問題。讓代碼變得更加優(yōu)雅是我們責(zé)無旁貸的任務(wù)

策略模式

  • 設(shè)計原則
    多用組合稚虎,少用繼承
    為什么要如此做,下面會做出解釋序攘,現(xiàn)在心里先存著這個念頭
    talk is cheap,show me you code
// 飛行接口
public interface FlyBehavior {   
         public void fly();
}
//叫聲接口
public interface QuackBehavior {    
        public void quack();
}
//不會飛行的實現(xiàn)
public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I can't fly");
    }
}
//可以用翅膀飛行的實現(xiàn)
public class FlyWithWings implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("I'm flying");
    }
}
//不會叫的實現(xiàn)
public class MuteQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("slience");
    }
}
//會叫的實現(xiàn)
public class Squeak implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("squeak");
    }
}
//鴨子類
public abstract class Duck {
     FlyBehavior flyBehavior;
     QuackBehavior quackBehavior;
    public abstract void display();
    public void performFly(){
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }
    public void setFlyBehavior(FlyBehavior flyBehavior){
        this.flyBehavior = flyBehavior;
    }
    public void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }
}
//具體的鴨子類
public class ModelDuck extends Duck {
    public ModelDuck(){
        flyBehavior = new FlyNoWay();
        quackBehavior = new Quack();
    }
    @Override
    public void display() {
        System.out.println("ModelDuck");
    }
}
//測試 結(jié)果
public class Test {
    public static void main(String[] args) {
        Duck duck = new ModelDuck();
        duck.performFly();
        duck.setFlyBehavior(new FlyWithWings());
        duck.performFly();
    }
}

上面代碼就是策略模式的內(nèi)容两踏,如果覺得十分疑惑兜喻,那就聽我慢慢道來梦染。

  • 背景
    某公司開發(fā)了一款十分歡迎的關(guān)于鴨子的游戲朴皆,游戲中有各種類型的鴨子,一邊游泳劃水肮疗。一邊呱呱叫扒接。有一天老板說,這個游戲太受歡迎了钾怔,我們要加入新的元素,要加入會飛的鴨子愚臀。兩天搞定7!男旗!
    于是這個任務(wù)被排到了小明身上。
  • 實現(xiàn)構(gòu)想
    其實小明拿到拍著胸脯的說到捧毛,兩天的時間太輕松了让网,于是他開始風(fēng)風(fēng)火火的做了起來。小明寫了一個Duck類溃睹,讓所有鴨子都繼承這一個類,用來保證得到的鴨子的行為一致性,不會出現(xiàn)玩家想要一個鴨子,這邊卻畫出來一只鸚鵡左刽。然后在Duck類里面實現(xiàn)了一個fly()方法,這樣也就成功的給子類鴨子加上了fly的飛行方法。但是這樣做會導(dǎo)致所有的鴨子都具有飛行茶没。所以這個做法被否決了。
    后來小明冥思苦想喂急,解決了這個問題笛求,他在Duck類里面把fly()方法 定義成抽象的,Duck的子類都需要自己實現(xiàn)這個方法探入,如果不會飛的鴨子就把fly()方法實現(xiàn)為不會飛,如果會飛的鴨子就把fly()是實現(xiàn)為會飛步氏,這樣會導(dǎo)致每種類型的鴨子必須實現(xiàn)fly()方法徒爹,如果鴨子種類太多,但就兩種類型隆嗅,會飛和不會飛。就會導(dǎo)致代碼里面寫了十多次的fly()方法的實現(xiàn)泡躯。
  • 策略模式
    正巧這個實現(xiàn)被路過的主席大神看到了,和小明巴拉巴拉說了一通较剃,小明頓感敬佩之情如同滔滔江水,絡(luò)繹不絕惰拱。而主席大神所說的便是上面的代碼啊送,也就是 策略模式

代碼分析


  • 分開變化和不會變化的部分
    首先肯定要有Duck類馋没,用來定義一些鴨子其他的屬性,比如 腿和嘴的個數(shù)等勾怒。而會變化只有一個fly()款票。那就要把fly 和 duck 分離開來。代碼里是定義了一個接口FlyBehavior 艾少,然后FlyBehavior 和FlyWithWings實現(xiàn)了它 。先解釋一些為什么要如此做幔妨,因為我們應(yīng)該面向接口編程谍椅,而不是面向?qū)ο缶幊獭?/li>
//片段一
Dog d = new Dog();
d.bark();
//片段二
Animal animal = new Dog();
animal.makeSound;
//片段三
a = getAnimal();
a.makeSound();

通過上面三個片段,讀者可以自己理解一些面向接口的含義锁施,第一個直接new Dog(); 第二個用到了接口杖们,第三個才是最好的實現(xiàn)悉抵,它表述的含義為摘完,外面并不知道getAnimal()里面是如何實現(xiàn)的,或者說他獲得的是什么列粪。外面唯一知道的是getAnimal獲得的動物會叫。所以可以調(diào)用makeSound()方法岂座,會叫的動物很多,包括鸚鵡吃媒,鴨子吕喘,狗刑桑。
而在大神的代碼里面向接口體現(xiàn)在 Duck類里面的performFly()方法里面的flyBehaviro.fly()

  • 實現(xiàn)鴨子的行為
    定義了FlyBehavior接口祠斧,F(xiàn)lyNoWay和FlyWithWings 實現(xiàn)了它。
    對于不同的鴨子我們可以給飛行這個行為做不同的實現(xiàn)辕漂,而在真實的ModelDuck 鴨子類初始化過程中賦一個值即可吴超。或者也通過 setFlyBehavior()方法改變鴨子行為跋涣。
    對于多用組合鸟悴,少用繼承的理解,

組合在上面代碼指的是细诸,Duck這個抽象類里面包括FlyBehavior 和QuackBehavior這兩個接口,這表明fly和quack這兩個行為是通過組合來實現(xiàn)的利赋,即一個Duck類擁有兩個屬性,而不是通過繼承獲得的

測試執(zhí)行的結(jié)果為

I can't fly
I'm flying

上面說的不是很詳細(xì)屏歹,因為有些東西并不需要講解。理解東西的話蝙眶,沒有比看代碼更好的途徑了

遲來的需求

  • 小明該如何做褪那?
    要有的鴨子會叫式塌,有的鴨子不會叫。這樣該如何實現(xiàn)那偏窝?
    上面代碼已經(jīng)實現(xiàn)好了武学,可以略作參考。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末硼补,一起剝皮案震驚了整個濱河市熏矿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌票编,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲤竹,死亡現(xiàn)場離奇詭異吊趾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)揩尸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門屁奏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坟瓢,你說我怎么就攤上這事≌哿” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵奕坟,是天一觀的道長。 經(jīng)常有香客問我月杉,道長,這世上最難降的妖魔是什么桨昙? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任腌歉,我火速辦了婚禮,結(jié)果婚禮上滤否,老公的妹妹穿的比我還像新娘最仑。我一直安慰自己炊甲,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布吟吝。 她就那樣靜靜地躺著颈娜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪官辽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天萤捆,我揣著相機(jī)與錄音俗批,去河邊找鬼。 笑死岁忘,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的帅腌。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼揩懒,長吁一口氣:“原來是場噩夢啊……” “哼挽封!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辅愿,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤点待,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后癞埠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颠区,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年通铲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朋截。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡吧黄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饲宿,到底是詐尸還是另有隱情胆描,我是刑警寧澤瘫想,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布国夜,位于F島的核電站短绸,受9級特大地震影響筹裕,放射性物質(zhì)發(fā)生泄漏窄驹。R本人自食惡果不足惜朝卒,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一抗斤、第九天 我趴在偏房一處隱蔽的房頂上張望丈咐。 院中可真熱鬧,春花似錦棵逊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至键菱,卻和暖如春今布,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背部默。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工傅蹂, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人份蝴。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像浸卦,于是被迫代替她去往敵國和親案糙。 傳聞我的和親對象是個殘疾皇子靴庆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理怒医,服務(wù)發(fā)現(xiàn),斷路器焰薄,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • 客戶需求 程序設(shè)計 1入录、直接利用繼承如何蛤奥? 將以上四種行為全部寫到Duck這個基類中,然后子類重寫飛和叫的行為僚稿。但...
    BlainPeng閱讀 474評論 2 7
  • 模擬鴨子游戲的需求 SimUDuck游戲中會出現(xiàn)各種鴨子凡桥,一邊游泳戲水,一邊呱呱叫蚀同。通過標(biāo)準(zhǔn)的OO技術(shù)缅刽,設(shè)計一個超...
    一縷陽憶往昔閱讀 475評論 2 0
  • 一部電影衰猛,竟讓一個28歲的女人的人生如同坐過山車一般,從高峰到低谷刹孔,似乎只在一瞬間啡省。沒有爭議,就沒有關(guān)注髓霞,關(guān)注...
    流箐c閱讀 3,647評論 46 86
  • 風(fēng) 今天站在陽臺上有些清冷卦睹。 想念武漢春天輕柔的風(fēng),吹面不寒楊柳風(fēng)方库。帶著柳絮兒结序,春風(fēng)不相識,不知不覺拂綠了...
    天天鍛煉吃零食閱讀 170評論 0 1