設(shè)計模式(二十一)策略模式

1秉颗、概述

策略模式是一種行為設(shè)計模式痢毒, 它能讓你定義一系列算法, 并將每種算法分別放入獨立的類中蚕甥, 以使算法的對象能夠相互替換哪替。

2、使用場景

1)當你想使用對象中各種不同的算法變體梢灭, 并希望能在運行時切換算法時夷家, 可使用策略模式。
2)當你有許多僅在執(zhí)行某些行為時略有不同的相似類時敏释, 可使用策略模式库快。
3)如果算法在上下文的邏輯中不是特別重要, 使用該模式能將類的業(yè)務(wù)邏輯與其算法實現(xiàn)細節(jié)隔離開來钥顽。
4)當類中使用了復(fù)雜條件運算符以在同一算法的不同變體中切換時义屏, 可使用該模式。實際就是減少邏輯判斷蜂大。

3闽铐、實例

以支付寶、微信支付舉例:
創(chuàng)建一個支付接口:

package com.cloud.bssp.designpatterns.Strategy;

/**
 * 支付策略接口
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public interface IPayStrategy {

    /**
     * 支付
     */
    void pay();
}

定義其兩個實現(xiàn)類:

/**
 * 微信
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class WXPay implements IPayStrategy{

    @Override
    public void pay() {
        System.out.println("使用微信支付");
    }
}
/**
 * 支付寶
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class ZFBPay implements IPayStrategy{

    @Override
    public void pay() {
        System.out.println("使用支付寶支付");
    }
}

測試類奶浦,有客戶端判斷使用那種方式兄墅,在代碼里面需要些邏輯判斷:

/**
 * 測試類
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class TestDemo {

    public static void main(String[] args) {
        IPayStrategy wxPay = new WXPay();
        IPayStrategy zfbPay = new ZFBPay();

        boolean flag = true;
        if (flag) {
            wxPay.pay();
        } else {
            zfbPay.pay();
        }
    }
}

結(jié)果:

使用微信支付

下面我們看看如何消除客戶端中的if、else:
增加一個枚舉類澳叉,在枚舉類內(nèi)部提供newInstance方法隙咸,根據(jù)傳入code值進行支付方式的初始化。

/**
 * 支付策略
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public enum PayStrategyEnum {


    /**
     * weixin
     */
    WEIXIN("weixin") {
        @Override
        public IPayStrategy create() {
            return new WXPay();
        }
    },
    /**
     * zhifubao
     */
    ZHIFUBAO("zhifubao") {
        @Override
        public IPayStrategy create() {
            return new ZFBPay();
        }
    };

    /**
     * 根據(jù)枚舉值獲取bean實例
     * @param analyseTypeEnum
     * @return
     */
    public static IPayStrategy newInstance(PayStrategyEnum analyseTypeEnum) {
        return analyseTypeEnum.create();
    }

    public abstract IPayStrategy create();

    private String code;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    PayStrategyEnum(String code) {
        this.code = code;
    }

    /**
     * 根據(jù)code獲取枚舉
     * @param code
     * @return
     */
    public static PayStrategyEnum getEnum(String code) {
        for (PayStrategyEnum value : values()) {
            if (value.getCode().equals(code)) {
                return value;
            }
        }
        return null;
    }

}

測試類

/**
 * 測試類
 * @date: 2021/1/25
 * @author weirx
 * @version 3.0
 */
public class TestDemo {

    public static void main(String[] args) {
        IPayStrategy wx = PayStrategyEnum.newInstance(PayStrategyEnum.getEnum("weixin"));
        wx.pay();

        IPayStrategy zfb = PayStrategyEnum.newInstance(PayStrategyEnum.getEnum("zhifubao"));
        zfb.pay();
    }
}

結(jié)果:

使用微信支付
使用支付寶支付

4成洗、分析

IPayStrategy.png

通過策略模式五督,使我們的代碼非常的簡潔。
客戶端只與支付策略接口和枚舉類有關(guān)系瓶殃,不需要關(guān)心具體的支付方法充包。
利于擴展其他支付方式,而不需要修改原有的代碼遥椿。
使用枚舉方式減少我們代碼中的if基矮、else等的邏輯判斷淆储,增加可讀性。

5愈捅、總結(jié)

優(yōu)點:
1)你可以在運行時切換對象內(nèi)的算法遏考。
2)你可以將算法的實現(xiàn)和使用算法的代碼隔離開來。
3)開閉原則蓝谨。 你無需對上下文進行修改就能夠引入新的策略灌具。
缺點:
1)如果你的算法極少發(fā)生改變, 那么沒有任何理由引入新的類和接口譬巫。 使用該模式只會讓程序過于復(fù)雜咖楣。
2)客戶端必須知曉策略間的不同——它需要選擇合適的策略。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芦昔,一起剝皮案震驚了整個濱河市诱贿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咕缎,老刑警劉巖珠十,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異凭豪,居然都是意外死亡焙蹭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門嫂伞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孔厉,“玉大人,你說我怎么就攤上這事帖努∽颍” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵拼余,是天一觀的道長污桦。 經(jīng)常有香客問我,道長匙监,這世上最難降的妖魔是什么凡橱? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮舅柜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躲惰。我一直安慰自己致份,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布础拨。 她就那樣靜靜地躺著氮块,像睡著了一般绍载。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滔蝉,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天击儡,我揣著相機與錄音,去河邊找鬼蝠引。 笑死阳谍,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的螃概。 我是一名探鬼主播矫夯,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吊洼!你這毒婦竟也來了训貌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤冒窍,失蹤者是張志新(化名)和其女友劉穎递沪,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體综液,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡款慨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了意乓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片樱调。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖届良,靈堂內(nèi)的尸體忽然破棺而出笆凌,到底是詐尸還是另有隱情,我是刑警寧澤士葫,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布乞而,位于F島的核電站,受9級特大地震影響慢显,放射性物質(zhì)發(fā)生泄漏爪模。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一荚藻、第九天 我趴在偏房一處隱蔽的房頂上張望屋灌。 院中可真熱鬧,春花似錦应狱、人聲如沸共郭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽除嘹。三九已至写半,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尉咕,已是汗流浹背叠蝇。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留年缎,地道東北人悔捶。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像晦款,于是被迫代替她去往敵國和親炎功。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348