還為那些設(shè)計(jì)模式煩惱嗎—策略模式

策略模式

</br>

前言

很多人在閱讀第三方框架(例如Retrofit)的時(shí)候犬庇,不太懂或者比較吃力喳篇,是因?yàn)槲覀內(nèi)鄙僖恍懘a的思維敌买,看代碼的設(shè)計(jì)的模式藤乙,今天猜揪,小菜我說下對(duì)策略模式的理解
</br>


介紹

  • 專業(yè)說法:定義了一系列的算法,并將每個(gè)算法封裝起來坛梁,而且使它們還可以相互替換而姐,策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化
  • 例子說法:假設(shè),今天划咐,我要為舍友煮一道菜拴念,小菜我買了一塊豬肉,但是褐缠,舍友開心的時(shí)候政鼠,是喜歡吃紅燒肉,則我要做紅燒肉队魏;難過的時(shí)候公般,是喜歡吃燜豬肉,則我要做燜豬肉:
    1.難過(策略)->做紅燒肉(算法)
    2.開心(策略)->做燜豬肉(算法)
    </br>

改善前的代碼

/**
 * Created by Jenchar on 2016/7/30.
 */
public class Meat {
    public static final String HAPPY="開心";
    public static final String SAD="難過";
    public static final String REDMEAT="紅燒肉";
    public static final String BRAISEMEAT="燜豬肉";

    public static void main(String[] args) {
        Meat meat=new Meat();
        meat.chooseFood(SAD,BRAISEMEAT);
    }
    private void chooseFood(String fellings,String type) {
        if(fellings.equals(HAPPY)){
            codeRedMeat(type);
        }else{
            cookBraiseMeat(type);
        }
    }

    private void cookBraiseMeat(String meat) {
        System.out.println("他"+HAPPY+"的時(shí)候器躏,"+"我要為他煮"+meat);
    }

    private void codeRedMeat(String meat) {
        System.out.println("他"+SAD+"的時(shí)候俐载,"+"我要為他煮"+meat);
    }
}

輸出結(jié)果:
他難過的時(shí)候,我要為他煮紅燒肉
分析:

Meat類很明顯的問題是并不是單一職責(zé)(簡(jiǎn)單來說登失,就是一個(gè)類只有一種功能)遏佣,首先它承擔(dān)了做紅燒肉和做燜豬肉的職責(zé),另一個(gè)問題就是通過if-else的形式來判斷做哪一種揽浙。小菜想状婶,當(dāng)我舍友他發(fā)神經(jīng)病,興奮的時(shí)候馅巷,會(huì)喜歡吃炸豬肉呢膛虫,那么我就需要在Meat類中增加一個(gè)方法去做炸豬肉,并且要在 chooseFood(String fellings,String type)方法里又增加一個(gè)判斷钓猬,代碼如下:
</br>

/**
 * Created by Jenchar on 2016/7/30.
 */
public class Meat {
    public static final String HAPPY="開心";
    public static final String SAD="難過";
    public static final String REDMEAT="紅燒肉";
    public static final String BRAISEMEAT="燜豬肉";
    /**
     * 增加的
     */
    public static final String  EXCITED="興奮";
    public static final String  FLYINGMEAT="炸豬肉";

    public static void main(String[] args) {
        Meat meat=new Meat();
        meat.chooseFood(EXCITED,FLYINGMEAT);

    }
    private void chooseFood(String fellings,String type) {
        if(fellings.equals(HAPPY)){
            codeRedMeat(type);
        }else if(fellings.equals(SAD)){
            cookBraiseMeat(type);
            /**
             * 增加的
             */
        }else if(fellings.equals(EXCITED)){
            cookFlyingMeat(type);
        }
    }

    /**
     *增加的
     */
    private void cookFlyingMeat(String type) {
        System.out.println("他"+EXCITED+"的時(shí)候稍刀,"+"我要為他煮"+type);
    }

    private void cookBraiseMeat(String meat) {
        System.out.println("他"+HAPPY+"的時(shí)候,"+"我要為他煮"+meat);
    }

    private void codeRedMeat(String meat) {
        System.out.println("他"+SAD+"的時(shí)候,"+"我要為他煮"+meat);
    }
}
輸出結(jié)果:
他興奮的時(shí)候账月,我要為他煮炸豬肉

再分析:

看看 chooseFood(String fellings,String type)這個(gè)方法综膀,現(xiàn)在代碼是不是很亂了,各種if-else語句纏繞在其中局齿?當(dāng)小菜的舍友剧劝,因?yàn)榫穹至眩窒氤粤硗庖环N抓歼,那么讥此,我又要在chooseFood增加if-else。當(dāng)if-else語句多了谣妻,就會(huì)很容易看錯(cuò)萄喳,寫錯(cuò),而且蹋半,代碼臃腫取胎,小的項(xiàng)目,小的類雖然過得去湃窍,但是到了大的項(xiàng)目,必然會(huì)很亂匪傍,難以維護(hù)您市。所以,因這種情況 役衡,小菜我開始引進(jìn)了一種設(shè)計(jì)模式茵休,“策略模式”
</br>


改善后的代碼

首先小菜我需要定義一個(gè)抽象的做肉接口,命名CookStrategy,代碼如下:

/**
 * 做肉的接品
 */
public interface CookStrategy {
    /**
     * 根據(jù)舍友的情感來做肉
     * @param feelings
     */
    void cook(String feelings);
}

接著對(duì)于做紅燒肉還是燜豬肉手蝎,小菜我覺得應(yīng)該都有一個(gè)獨(dú)立的做肉策略類榕莺,這些類都實(shí)現(xiàn)上面說的CookStrategy接口,代碼如下:
CookRedMeat.java:

/**
 * 做紅燒肉的類
 */
public class CookRedMeat implements CookStrategy{
    public static final String REDMEAT="紅燒肉";
    /**
     * 開始做他喜歡的紅燒肉
     * @param feelings
     */
    @Override
    public void cook(String feelings) {
        System.out.println("他"+feelings+"的時(shí)候棵介,"+"我要為他煮"+REDMEAT);
    }
}

CookBraiseMeat.java:

/**
 * 做燜肉的類
 */
public class CookBraiseMeat implements CookStrategy {
    public static final String BRAISEMEAT="燜豬肉";
    @Override
     /**
     * 開始做他喜歡的燜豬肉
     * @param feelings
     */
    public void cook(String feelings) {
          System.out.println("他"+feelings+"的時(shí)候钉鸯,"+"我要為他煮"+BRAISEMEAT);
    }
}

最后,我們?cè)賱?chuàng)建一個(gè)的Meat類邮辽。

public class Meat {
    public static final String HAPPY="開心";
    public static final String SAD="難過";
    /**
     * 持有CookStrategy對(duì)象
     */
    private CookStrategy mCookStrategy;
    public static void main(String[] args) {
        Meat meat=new Meat();
        meat.setCookStrategy(new CookBraiseMeat());
        meat.cookFood(SAD);
    }

    /**
     * 把子類的引用賦值到mCookStrategy,就可以調(diào)用子類的方法唠雕。
     * @param cookStrategy
     */
    private void setCookStrategy(CookStrategy cookStrategy) {
        mCookStrategy=cookStrategy;
    }
    private void cookFood(String feelings){
        mCookStrategy.cook(feelings);
    }

}
最后分析

通過改善前后的代碼,可以看出:

  • 前者:通過if-else解決問題吨述,代碼臃腫岩睁,邏輯復(fù)雜,難以升級(jí)與維護(hù)揣云,沒有結(jié)構(gòu)可言
  • 后者:通過建立接口捕儒,將不同的策略構(gòu)建成一個(gè)具體的策略實(shí)現(xiàn) ,通過不同的策略實(shí)現(xiàn)算法替換,從而更好地增加擴(kuò)展性邓夕,直觀性刘莹。
    </br>

結(jié)論與使用場(chǎng)景

  • 針對(duì)同一類型的問題阎毅,多種處理,僅僅是具體為行有差別(做紅燒肉栋猖,做燜豬肉)
  • 出現(xiàn)同一抽象類有多個(gè)子類净薛,雖然使用if-else或者switch-case來選擇子類的(根據(jù)舍友的心情來做肉)
  • 需要安全地封裝多種同一類型的操作時(shí)(做紅燒肉,做燜豬肉這些操作時(shí))
    </br>

喜歡我的朋友蒲拉,可以與我一起討論問題肃拜,我也是學(xué)習(xí)者,希望與大學(xué)一起學(xué)習(xí)雌团。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末燃领,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锦援,更是在濱河造成了極大的恐慌猛蔽,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灵寺,死亡現(xiàn)場(chǎng)離奇詭異曼库,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)略板,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門毁枯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叮称,你說我怎么就攤上這事种玛。” “怎么了瓤檐?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵赂韵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我挠蛉,道長(zhǎng)祭示,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任碌秸,我火速辦了婚禮绍移,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘讥电。我一直安慰自己蹂窖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布恩敌。 她就那樣靜靜地躺著瞬测,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上月趟,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天灯蝴,我揣著相機(jī)與錄音,去河邊找鬼孝宗。 笑死穷躁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的因妇。 我是一名探鬼主播问潭,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼婚被!你這毒婦竟也來了狡忙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤址芯,失蹤者是張志新(化名)和其女友劉穎灾茁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谷炸,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡北专,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旬陡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逗余。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖季惩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腻格,我是刑警寧澤画拾,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站菜职,受9級(jí)特大地震影響青抛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酬核,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一蜜另、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫡意,春花似錦举瑰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春耸序,著一層夾襖步出監(jiān)牢的瞬間忍些,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工坎怪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罢坝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓搅窿,卻偏偏與公主長(zhǎng)得像嘁酿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子戈钢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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

  • 1 場(chǎng)景問題# 1.1 報(bào)價(jià)管理## 向客戶報(bào)價(jià)痹仙,對(duì)于銷售部門的人來講,這是一個(gè)非常重大殉了、非常復(fù)雜的問題开仰,對(duì)不同的...
    七寸知架構(gòu)閱讀 5,092評(píng)論 9 62
  • 1 場(chǎng)景問題 1.1 報(bào)價(jià)管理 向客戶報(bào)價(jià),對(duì)于銷售部門的人來講薪铜,這是一個(gè)非常重大众弓、非常復(fù)雜的問題,對(duì)不同的客戶要...
    4e70992f13e7閱讀 3,091評(píng)論 2 16
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程隔箍,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • 工廠模式類似于現(xiàn)實(shí)生活中的工廠可以產(chǎn)生大量相似的商品谓娃,去做同樣的事情,實(shí)現(xiàn)同樣的效果;這時(shí)候需要使用工廠模式蜒滩。簡(jiǎn)單...
    舟漁行舟閱讀 7,777評(píng)論 2 17
  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是策略模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 策略模式和模板方法模式的區(qū)別 優(yōu)點(diǎn)和...
    w1992wishes閱讀 862評(píng)論 1 7