策略模式-設(shè)計模式學(xué)習(xí)

文字理解

分析下定義帆疟,策略模式定義和封裝了一系列的算法蚁吝,它們是可以相互替換的,也就是說它們具有共性垦缅,而它們的共性就體現(xiàn)在策略接口的行為上冲泥,另外為了達(dá)到最后一句話的目的,也就是說讓算法獨立于使用它的客戶而獨立變化壁涎,我們需要讓客戶端依賴于策略接口凡恍。

使用場景

1.針對同一類型問題的多種處理方式,僅僅是具體行為有差別時怔球;
2.需要安全地封裝多種同一類型的操作時嚼酝;
3.出現(xiàn)同一抽象類有多個子類,而又需要使用 if-else 或者 switch-case 來選擇具體子類時庞溜。

簡單描述

定義一個接口(例如計價接口)革半,多個類去實現(xiàn)這個接口(多種計價模式A,B流码,C)又官,最后再有一個類是實際計算的類Context,如果按照A計價模式計價漫试,只需new Context()時候六敬,調(diào)用ContextInterface()方法,ContextInterface()是根據(jù)傳入的策略對象來選擇其調(diào)用的接口方法的驾荣,從而實現(xiàn)策略選擇.

public class Context {
    //持有一個具體策略的對象
    private Strategy strategy;
    /**
     * 構(gòu)造函數(shù)外构,傳入一個具體策略對象
     * @param strategy    具體策略對象
     */
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 策略方法
     */
    public void contextInterface(){

        strategy.strategyInterface();
    }

}

代碼理解

假設(shè)鵝廠推出了3種會員普泡,分別為會員,超級會員以及金牌會員审编,還有就是普通玩家撼班,針對不同類別的玩家,購買《王者農(nóng)藥》皮膚有不同的打折方式垒酬,并且一個顧客每消費(fèi)10000就增加一個級別砰嘁,那么我們就可以使用策略模式,因為策略模式描述的就是算法的不同勘究,這里我們舉例就采用最簡單的矮湘,以上四種玩家分別采用原價(普通玩家),九折口糕,八折和七價的收錢方式缅阳。

那么我們首先要有一個計算價格的策略接口

public interface CalPrice {
    //根據(jù)原價返回一個最終的價格
    Double calPrice(Double orgnicPrice);
}

下面是4種玩家的計算方式的實現(xiàn)

public class Orgnic implements CalPrice {

    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice;
    }
}
public class Vip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.9;
    }
}
public class SuperVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.8;
    }
}
public class GoldVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.7;
    }
}

我們看客戶類,我們需要客戶類幫我們完成玩家升級的功能景描。

public class Player {
    private Double totalAmount = 0D;//客戶在鵝廠消費(fèi)的總額
    private Double amount = 0D;//客戶單次消費(fèi)金額
    private CalPrice calPrice = new Orgnic();//每個客戶都有一個計算價格的策略十办,初始都是普通計算,即原價

    //客戶購買皮膚伏伯,就會增加它的總額
    public void buy(Double amount) {
        this.amount = amount;
        totalAmount += amount;
        if (totalAmount > 30000) {//30000則改為金牌會員計算方式
            calPrice = new GoldVip();
        } else if (totalAmount > 20000) {//類似
            calPrice = new SuperVip();
        } else if (totalAmount > 10000) {//類似
            calPrice = new Vip();
        }
    }

    //計算客戶最終要付的錢
    public Double calLastAmount() {
        return calPrice.calPrice(amount);
    }
}

接下來是客戶端調(diào)用橘洞,系統(tǒng)會幫我們自動調(diào)整收費(fèi)策略捌袜。


public class Client {
    public static void main(String[] args) {
        Player player = new Player();
        player.buy(5000D);
        System.out.println("玩家需要付錢:" + player.calLastAmount());
        player.buy(12000D);
        System.out.println("玩家需要付錢:" + player.calLastAmount());
        player.buy(12000D);
        System.out.println("玩家需要付錢:" + player.calLastAmount());
        player.buy(12000D);
        System.out.println("玩家需要付錢:" + player.calLastAmount());
    }
}

運(yùn)行以后會發(fā)現(xiàn)说搅,第一次是原價,第二次是九折虏等,第三次是八折弄唧,最后一次則是七價。這樣設(shè)計的好處是霍衫,客戶不再依賴于具體的收費(fèi)策略候引,依賴于抽象永遠(yuǎn)是正確的。

在上面的基礎(chǔ)上敦跌,我們可以使用簡單工廠來稍微進(jìn)行優(yōu)化

public class CalPriceFactory {
    private CalPriceFactory(){}
    //根據(jù)客戶的總金額產(chǎn)生相應(yīng)的策略
    public static CalPrice createCalPrice(Player customer){
        if (customer.getTotalAmount() > 30000) {//3000則改為金牌會員計算方式
            return new GoldVip();
        }else if (customer.getTotalAmount() > 20000) {//類似
            return new SuperVip();
        }else if (customer.getTotalAmount() > 10000) {//類似
            return new Vip();
        }else {
            return new Orgnic();
        }
    }
}

這樣就將制定策略的功能從客戶類分離了出來澄干,我們的客戶類可以變成這樣。

public class Player {
    private Double totalAmount = 0D;//客戶在鵝廠消費(fèi)的總額
    private Double amount = 0D;//客戶單次消費(fèi)金額
    private CalPrice calPrice = new Orgnic();//每個客戶都有一個計算價格的策略柠傍,初始都是普通計算麸俘,即原價

    //客戶購買皮膚,就會增加它的總額
    public void buy(Double amount) {
        this.amount = amount;
        totalAmount += amount;
        /* 變化點惧笛,我們將策略的制定轉(zhuǎn)移給了策略工廠从媚,將這部分責(zé)任分離出去 */
        calPrice = CalPriceFactory.createCalPrice(this);
    }

    //計算客戶最終要付的錢
    public Double calLastAmount() {
        return calPrice.calPrice(amount);
    }

    public Double getTotalAmount() {
        return totalAmount;
    }
}

雖然結(jié)合簡單工廠模式,我們的策略模式靈活了一些患整,但不免發(fā)現(xiàn)在工廠中多了if-else判斷拜效,也就是如果增加一個會員類別喷众,我又得增加一個else-if語句,這是簡單工廠的缺點紧憾,對修改開放到千。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市赴穗,隨后出現(xiàn)的幾起案子父阻,更是在濱河造成了極大的恐慌,老刑警劉巖望抽,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件加矛,死亡現(xiàn)場離奇詭異,居然都是意外死亡煤篙,警方通過查閱死者的電腦和手機(jī)斟览,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辑奈,“玉大人苛茂,你說我怎么就攤上這事○埃” “怎么了妓羊?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長稍计。 經(jīng)常有香客問我躁绸,道長,這世上最難降的妖魔是什么臣嚣? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任净刮,我火速辦了婚禮,結(jié)果婚禮上硅则,老公的妹妹穿的比我還像新娘淹父。我一直安慰自己,他們只是感情好怎虫,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布暑认。 她就那樣靜靜地躺著,像睡著了一般大审。 火紅的嫁衣襯著肌膚如雪蘸际。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天饥努,我揣著相機(jī)與錄音捡鱼,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛驾诈,可吹牛的內(nèi)容都是我干的缠诅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼乍迄,長吁一口氣:“原來是場噩夢啊……” “哼管引!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闯两,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤褥伴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后漾狼,有當(dāng)?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
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留特碳,地道東北人诚亚。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓晕换,卻偏偏與公主長得像,于是被迫代替她去往敵國和親站宗。 傳聞我的和親對象是個殘疾皇子闸准,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

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