設(shè)計模式--策略模式

什么是策略模式

在策略模式(Strategy Pattern)中尸曼,一個類的行為或其算法可以在運行時更改。這種類型的設(shè)計模式屬于行為型模式控轿。
在策略模式中解幽,我們創(chuàng)建表示各種策略的對象和一個行為隨著策略對象改變而改變的 context 對象。策略對象改變 context 對象的執(zhí)行算法片部。
其思想是針對一組算法,將每一種算法都封裝到具有共同接口的獨立的類中廊鸥,從而是它們可以相互替換辖所。策略模式的最大特點是使得算法可以在不影響客戶端的情況下發(fā)生變化缘回,從而改變不同的功能。

簡單解釋

參照大話設(shè)計模酥宴、菜鳥教程拙寡。1授滓、商場收費為例,無論原價收取肆糕、打折收取還是滿300減50般堆,這些都是一個一個的策略。2诚啃、外出旅行淮摔,無論選擇坐巴士、騎自行車或選擇飛機出生绍申,這都是一個一個的策略噩咪。這些策略都是隨時可能互相替換,且互相之前并不影響极阅。

  • 優(yōu)點
    1胃碾、算法可以自由切換筋搏。 2仆百、避免使用多重條件判斷。 3奔脐、擴展性良好俄周。
  • 缺點
    1、策略類會增多髓迎。 2峦朗、所有策略類都需要對外暴露。

代碼解釋

參照大話設(shè)計模式中的商場促銷排龄,商場促銷分別是打折波势、滿減或者原價收費,我們可以把計算收費做為抽象方法提取出來;
1尺铣、定義抽象類拴曲,將計算費用方法抽象;

/**
 * 抽象算法類凛忿,定義算法
 */
public abstract class Strategy {

    /**
     * 算法方法
     */
    public abstract Double getMoney(Double money);
}

2澈灼、分別定義子類,正常收費店溢、打折收費叁熔、滿減收費三個子類,繼承抽象類床牧,實現(xiàn)具體方法

/**
 * 正常收費
 */
public class StrategyNormal extends Strategy {

    @Override
    public Double getMoney(Double money) {
        System.out.println("正常收費");
        return money;
    }
}
/**
 * 打折收費
 */
public class StrategyRebate extends Strategy {

    private Double rebate;

    /**
     * 實例化時者疤,傳入具體打折參數(shù),例:打八折叠赦,則傳入0.8
     * @param rebate
     */
    public StrategyRebate(Double rebate){
        this.rebate=rebate;
    }

    @Override
    public Double getMoney(Double money) {
        return money*rebate;
    }
}
/**
 * 滿減收費 滿300減100
 */
public class StrategyReturn extends Strategy {

    private Double moneyCondition;
    private Double moneyReturn;

    /**
     * 傳滿足條件后,減多少費用
     * @param moneyCondition 條件
     * @param moneyReturn 減免條件
     */
    public StrategyReturn(Double moneyCondition,Double moneyReturn){
        this.moneyCondition=moneyCondition;
        this.moneyReturn=moneyReturn;
    }

    @Override
    public Double getMoney(Double money) {
        if(money>=this.moneyCondition){
            return money-this.moneyReturn;
        }
        return money;
    }
}

3革砸、定義一個配置類除秀,維護針對于算法的引用

/**
 * 針對于算法的引用,根據(jù)具體的策略對象調(diào)用其算法方法
 */
public class StrateContext {

    private Strategy strategy;

    public StrateContext(Strategy strategy){
        this.strategy=strategy;
    }

    public Double getMoney(Double money){
        return strategy.getMoney(money);
    }
    /**
     * 示例
     * @param args
     */
    public static void main(String[] args) {
        //正常收費
        StrateContext context=new StrateContext(new StrategyNormal());
        Double d1=context.getMoney(100.0d);
        System.out.println("正常收費:"+d1);

        //滿300減100
        StrateContext context1=new StrateContext(new StrategyReturn(300d,100d));
        Double d2=context1.getMoney(350d);
        System.out.println("滿300減100:"+d2);

        //打八折
        StrateContext context2=new StrateContext(new StrategyRebate(0.8d));
        Double d3=context2.getMoney(100d);
        System.out.println("打八折:"+d3);
    }
}

后記

以上代碼僅僅實現(xiàn)了策略模式的簡單使用算利,通常業(yè)務(wù)代碼中可能還要更復雜册踩,但是萬變不離其中,通過將策略模式與工廠模式接合效拭,將可以實現(xiàn)代碼應(yīng)用的松藕合暂吉;

與工廠模式接合

獲取每一個策略都需要進行客戶端的判斷,代碼耦合太緊缎患,同時不利于后期維護慕的,僅僅這樣處理那么與采取策略模式的初衷不符;
1挤渔、創(chuàng)建一個工廠類肮街,用于實例化計算類

public class StrateContextFac {

    private Strategy strategy;

    public StrateContextFac(String type){
        switch (type){
            case "正常收費":
                strategy=new StrategyNormal();
                break;
            case "滿300減100":
                strategy=new StrategyReturn(300d,100d);
                break;
            case "打八折":
                strategy=new StrategyRebate(0.8d);
                break;
        }
    }
    public Double getMoney(double money){
        return strategy.getMoney(money);
    }

}

2、調(diào)用計算

public static void contextFac(){
        String type="打八折";
        StrateContextFac fac=new StrateContextFac(type);
        Double money=fac.getMoney(100d);
        System.out.println(type+":"+money);
    }

與工廠模式接合后判导,只需要關(guān)心傳入的類型與數(shù)據(jù)嫉父,而不需要去維護相關(guān)的計算類,計算類由工廠直接調(diào)用并生成眼刃;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绕辖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子擂红,更是在濱河造成了極大的恐慌仪际,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弟头,居然都是意外死亡吩抓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門赴恨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疹娶,“玉大人,你說我怎么就攤上這事伦连∮杲龋” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵惑淳,是天一觀的道長额港。 經(jīng)常有香客問我,道長歧焦,這世上最難降的妖魔是什么移斩? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮绢馍,結(jié)果婚禮上向瓷,老公的妹妹穿的比我還像新娘。我一直安慰自己舰涌,他們只是感情好猖任,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓷耙,像睡著了一般朱躺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搁痛,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天长搀,我揣著相機與錄音,去河邊找鬼落追。 笑死盈滴,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的轿钠。 我是一名探鬼主播巢钓,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疗垛!你這毒婦竟也來了症汹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贷腕,失蹤者是張志新(化名)和其女友劉穎背镇,沒想到半個月后咬展,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡瞒斩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年破婆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胸囱。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡祷舀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烹笔,到底是詐尸還是另有隱情裳扯,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布谤职,位于F島的核電站饰豺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏允蜈。R本人自食惡果不足惜冤吨,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望饶套。 院中可真熱鬧锅很,春花似錦、人聲如沸凤跑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仔引。三九已至,卻和暖如春褐奥,著一層夾襖步出監(jiān)牢的瞬間咖耘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工撬码, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留儿倒,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓呜笑,卻偏偏與公主長得像夫否,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子叫胁,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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