4.設(shè)計(jì)模式-委派模式以及策略模式

委派模式(Delegate Pattern)

  • 介紹:委派模式(Delegate Pattern)的基本作用就是負(fù)責(zé)任務(wù)的調(diào)度和分配任何摔寨,跟代理模式很像,可以看做是一種情況下的靜態(tài)代理的的全權(quán)代理,但是代理模式注重過程宙拉,而委派模式注重結(jié)果
    不屬于 23 中涉及模式之一
    屬于行為型模式笨触。
    java中Delegate 結(jié)尾的一般都是委派懦傍,包含Dispatcher 也是(spring 中DispatcherServlet就是使用委派模式)
  • 使用場景
    1. 一件事情(或一個(gè)請求)對象本身不知道怎樣處理,對象把請求交給其它對象來做
  • 優(yōu)點(diǎn): 對內(nèi)隱藏實(shí)現(xiàn), 易于擴(kuò)展; 簡化調(diào)用芦劣。
  • 缺點(diǎn):和靜態(tài)代理的一樣粗俱,當(dāng)如果員工和leader類拓展的時(shí)候容易膨脹,難于管理虚吟。
//現(xiàn)實(shí)生活中也常有委 派的場景發(fā)生源梭,例如:老板(Boss)給項(xiàng)目經(jīng)理(Leader)下達(dá)任務(wù)娱俺,項(xiàng)目經(jīng)理會(huì)根據(jù) 實(shí)際情況給每個(gè)員工派發(fā)工作任務(wù),
//待員工把工作任務(wù)完成之后废麻,再由項(xiàng)目經(jīng)理匯報(bào)工 作進(jìn)度和結(jié)果給老板荠卷。我們用代碼來模擬下這個(gè)業(yè)務(wù)場景
public class Boss {

    public void command(String command,Leader leader){
        leader.doing(command);
    }

}


//實(shí)現(xiàn)一個(gè)接口,各自都有各自的工作
public interface ITarget {
    public void doing(String command);
}



public class Leader implements ITarget {

    private Map<String,ITarget> targets = new HashMap<String,ITarget>();
    // 初始化,會(huì)什么需要項(xiàng)目經(jīng)理知道
    public Leader() {
        targets.put("加密",new TargetA());
        targets.put("登錄",new TargetB());
    }

    //項(xiàng)目經(jīng)理自己不干活
    public void doing(String command){
        targets.get(command).doing(command);
    }

}




public class TargetA implements ITarget {
    @Override
    public void doing(String command) {
        System.out.println("我是員工A烛愧,我現(xiàn)在開始干" + command + "工作");
    }
}



public class TargetB implements ITarget {
    @Override
    public void doing(String command) {
        System.out.println("我是員工B油宜,我現(xiàn)在開始干" + command + "工作");
    }
}


// 客戶端調(diào)用
public class DelegateTest {

    public static void main(String[] args) {

        //客戶請求(Boss)、委派者(Leader)怜姿、被被委派者(Target)
        //委派者要持有被委派者的引用
        //代理模式注重的是過程慎冤, 委派模式注重的是結(jié)果
        //策略模式注重是可擴(kuò)展(外部擴(kuò)展),委派模式注重內(nèi)部的靈活和復(fù)用
        //委派的核心:就是分發(fā)沧卢、調(diào)度蚁堤、派遣

        //委派模式:就是靜態(tài)代理和策略模式一種特殊的組合

        new Boss().command("登錄",new Leader());
        //sout :我是員工B,我現(xiàn)在開始干登錄工作

    }

}



策略模式(Strategy Pattern)

  • 介紹:策略模式(Strategy Pattern)是指定義了算法家族但狭、分別封裝起來披诗,讓它們之間可以互 相替換,此模式讓算法的變化不會(huì)影響到使用算法的用戶
  • 使用場景
    1. 假如系統(tǒng)中有很多類立磁,而他們的區(qū)別僅僅在于他們的行為不同呈队。
    2. 一個(gè)系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種。
  • 優(yōu)點(diǎn)
    1. 策略模式符合開閉原則唱歧。
    2. 避免使用多重條件轉(zhuǎn)移語句宪摧,如 if...else...語句、switch 語句
    3. 使用策略模式可以提高算法的保密性和安全性颅崩。
  • 缺點(diǎn):
    1. 客戶端必須知道所有的策略几于,并且自行決定使用哪一個(gè)策略類。
    2. 代碼中會(huì)產(chǎn)生非常多策略類沿后,增加維護(hù)難度沿彭。
// 以訂單支付為例

//支付渠道 
public abstract class Payment {

    //支付類型
    public abstract String getName();

    //查詢余額
    protected abstract double queryBalance(String uid);

    //扣款支付
    public MsgResult pay(String uid, double amount) {
        if(queryBalance(uid) < amount){
            return new MsgResult(500,"支付失敗","余額不足");
        }
        return new MsgResult(200,"支付成功","支付金額:" + amount);
    }


}


// 多種支付
public class AliPay extends Payment {

    public String getName() {
        return "支付寶";
    }

    protected double queryBalance(String uid) {
        return 1998;
    }

}

public class JDPay extends Payment {

    public String getName() {
        return "京東支付";
    }

    protected double queryBalance(String uid) {
        return 998;
    }
}

//........



// 支付策略管理
public class PayStrategy {
    public static final String ALI_PAY = "AliPay";
    public static final String JD_PAY = "JdPay";
    public static final String DEFAULT_PAY = ALI_PAY;
    // ......

    private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
    static {
        payStrategy.put(ALI_PAY,new AliPay());
        payStrategy.put(JD_PAY,new JDPay());
        // .......
    }

    public static Payment get(String payKey){
        if(!payStrategy.containsKey(payKey)){
            return payStrategy.get(DEFAULT_PAY);
        }
        return payStrategy.get(payKey);
    }
}



// 支付完成以后的狀態(tài)
public class MsgResult {
    private int code;
    private Object data;
    private String msg;

    public MsgResult(int code, String msg, Object data) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public String toString(){
        return ("支付狀態(tài):[" + code + "]," + msg + ",交易詳情:" + data);
    }
}


//訂單
public class Order {
    private String uid;
    private String orderId;
    private double amount;

    // setget() \ constructron

    //完美地解決了switch的過程,不需要在代碼邏輯中寫switch了
    //更不需要寫if    else if
    public MsgResult pay(){
        return pay(PayStrategy.DEFAULT_PAY);
    }

    public MsgResult pay(String payKey){
        Payment payment = PayStrategy.get(payKey);
        System.out.println("歡迎使用" + payment.getName());
        System.out.println("本次交易金額為:" + amount + "得运,開始扣款...");
        return payment.pay(uid,amount);
    }
}

//客戶端調(diào)用
public class PayStrategyTest {

    public static void main(String[] args) {

        //省略把商品添加到購物車膝蜈,再從購物車下單
        //直接從點(diǎn)單開始
        Order order = new Order("1","20180311001000009",324.45);

        //開始支付锅移,選擇微信支付熔掺、支付寶、銀聯(lián)卡非剃、京東白條置逻、財(cái)付通
        //每個(gè)渠道它支付的具體算法是不一樣的
        //基本算法固定的

        //這個(gè)值是在支付的時(shí)候才決定用哪個(gè)值
        System.out.println(order.pay(PayStrategy.ALI_PAY));

        InstantiationStrategy

    }

}

// TODO 策略模式 可以用以上的抽象類,也可以使用接口

//源碼中涉及: Comparator接口   Arrays.parallelSort  \ TreeMap 構(gòu)造方法等  
//策略模式還可以繼承使用,請看:InstantiationStrategy\SimpleInstantiationStrategy\CglibSubclassingInstantiationStrategy


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市备绽,隨后出現(xiàn)的幾起案子券坞,更是在濱河造成了極大的恐慌鬓催,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恨锚,死亡現(xiàn)場離奇詭異宇驾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)猴伶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門课舍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人他挎,你說我怎么就攤上這事筝尾。” “怎么了办桨?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵筹淫,是天一觀的道長。 經(jīng)常有香客問我呢撞,道長损姜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任狸相,我火速辦了婚禮薛匪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘脓鹃。我一直安慰自己逸尖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布瘸右。 她就那樣靜靜地躺著娇跟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪太颤。 梳的紋絲不亂的頭發(fā)上苞俘,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音龄章,去河邊找鬼吃谣。 笑死,一個(gè)胖子當(dāng)著我的面吹牛做裙,可吹牛的內(nèi)容都是我干的岗憋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼锚贱,長吁一口氣:“原來是場噩夢啊……” “哼仔戈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤监徘,失蹤者是張志新(化名)和其女友劉穎晋修,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凰盔,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡墓卦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了户敬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趴拧。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖山叮,靈堂內(nèi)的尸體忽然破棺而出著榴,到底是詐尸還是另有隱情,我是刑警寧澤屁倔,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布脑又,位于F島的核電站,受9級特大地震影響锐借,放射性物質(zhì)發(fā)生泄漏问麸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一钞翔、第九天 我趴在偏房一處隱蔽的房頂上張望严卖。 院中可真熱鬧,春花似錦布轿、人聲如沸哮笆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稠肘。三九已至,卻和暖如春萝毛,著一層夾襖步出監(jiān)牢的瞬間项阴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工笆包, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留环揽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓庵佣,卻偏偏與公主長得像歉胶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子秧了,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

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