Java中的策略模式實例教程

英文原文:Strategy Design Pattern in Java – Example Tutorial
作者:Pankaj Kumar
譯者:f0tlo <1357654289@qq.com>
原文地址:http://t.cn/RzUiBNN

策略模式是一種行為模式。用于某一個具體的項目有多個可供選擇的算法策略咕别,客戶端在其運行時根據(jù)不同需求決定使用某一具體算法策略。

策略模式也被稱作政策模式止吁。實現(xiàn)過程為,首先定義不同的算法策略袱巨,然后客戶端把算法策略作為它的一個參數(shù)达吞。使用這種模式最好的例子是Collection.sort()方法了,它使用Comparator對象作為參數(shù)鹃两。根據(jù)Comparator接口不同實現(xiàn),對象會被不同的方法排序舀凛。詳細(xì)介紹請看java中的排序?qū)ο?/a>俊扳。

本文例子是,完成一個簡單地購物車猛遍,兩種付款策略可供選擇馋记,一為信用卡,另外一種為Paypal懊烤。

首先創(chuàng)建策略接口梯醒,在本文例子中,付款金額作為參數(shù)腌紧。

package com.journaldev.design.strategy;

public interface PaymentStrategy {

    public void pay(int amount);
}

現(xiàn)在實現(xiàn)使用信用卡及Paypal兩種算法策略的實體類茸习。

package com.journaldev.design.strategy;

public class CreditCardStrategy implements PaymentStrategy {

    private String name;
    private String cardNumber;
    private String cvv;
    private String dateOfExpiry;

    public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
        this.name=nm;
        this.cardNumber=ccNum;
        this.cvv=cvv;
        this.dateOfExpiry=expiryDate;
    }
    @Override
    public void pay(int amount) {
        System.out.println(amount +" paid with credit/debit card");
    }

}
package com.journaldev.design.strategy;

public class PaypalStrategy implements PaymentStrategy {

    private String emailId;
    private String password;

    public PaypalStrategy(String email, String pwd){
        this.emailId=email;
        this.password=pwd;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using Paypal.");
    }

}

此時,算法策略已經(jīng)準(zhǔn)備就緒壁肋,現(xiàn)在需要實現(xiàn)購物車以及能夠運用付款策略的支付方法号胚。

package com.journaldev.design.strategy;

public class Item {

    private String upcCode;
    private int price;

    public Item(String upc, int cost){
        this.upcCode=upc;
        this.price=cost;
    }

    public String getUpcCode() {
        return upcCode;
    }

    public int getPrice() {
        return price;
    }

}
package com.journaldev.design.strategy;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {

    //List of items
    List<Item> items;

    public ShoppingCart(){
        this.items=new ArrayList<Item>();
    }

    public void addItem(Item item){
        this.items.add(item);
    }

    public void removeItem(Item item){
        this.items.remove(item);
    }

    public int calculateTotal(){
        int sum = 0;
        for(Item item : items){
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(PaymentStrategy paymentMethod){
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}

注意,購物車的支付方法接受支付策略作為參數(shù)浸遗,但是不在其內(nèi)部保存任何實例變量猫胁。

一個簡單地測試程序。

package com.journaldev.design.strategy;

public class ShoppingCartTest {

    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        Item item1 = new Item("1234",10);
        Item item2 = new Item("5678",40);

        cart.addItem(item1);
        cart.addItem(item2);

        //pay by paypal
        cart.pay(new PaypalStrategy("myemail@example.com", "mypwd"));

        //pay by credit card
        cart.pay(new CreditCardStrategy("Pankaj Kumar", "1234567890123456", "786", "12/15"));
    }

}

輸出如下:

50 paid using Paypal.
50 paid with credit/debit card

策略模式UML圖:

重要點:

  • 此處可以構(gòu)建策略的實體變量跛锌,但是應(yīng)該盡量避免這種情況弃秆。因為需要保證對于特定的任務(wù)能夠?qū)?yīng)某個具體的算法策略,與Collection.sort()Array.sort()方法使用comparator作為參數(shù)道理類似察净。
  • 策略模式類似與狀態(tài)模式驾茴。兩者之間的不同,狀態(tài)模式中的Context(環(huán)境對象)包含了狀態(tài)的實例變量氢卡,并且不同的任務(wù)依賴同一個狀態(tài)。相反晨缴,在策略模式中策略是作為一個參數(shù)傳遞進(jìn)方法中译秦,context(環(huán)境對象)不需要也不能存儲任何變量。
  • 當(dāng)一組算法對應(yīng)一個任務(wù),并且程序可以在運行時靈活的選擇其中一個算法筑悴,策略模式是很好的選擇们拙。

這就是全部的Java策略模式,希望你喜歡上它了阁吝。

  • 序言:七十年代末砚婆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子突勇,更是在濱河造成了極大的恐慌装盯,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甲馋,死亡現(xiàn)場離奇詭異埂奈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)定躏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門账磺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痊远,你說我怎么就攤上這事垮抗。” “怎么了碧聪?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵冒版,是天一觀的道長。 經(jīng)常有香客問我矾削,道長壤玫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任哼凯,我火速辦了婚禮欲间,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘断部。我一直安慰自己猎贴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布蝴光。 她就那樣靜靜地躺著她渴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔑祟。 梳的紋絲不亂的頭發(fā)上趁耗,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音疆虚,去河邊找鬼苛败。 笑死满葛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的罢屈。 我是一名探鬼主播嘀韧,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缠捌!你這毒婦竟也來了锄贷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤曼月,失蹤者是張志新(化名)和其女友劉穎谊却,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體十嘿,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡因惭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绩衷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹦魔。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖咳燕,靈堂內(nèi)的尸體忽然破棺而出勿决,到底是詐尸還是另有隱情,我是刑警寧澤招盲,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布低缩,位于F島的核電站,受9級特大地震影響曹货,放射性物質(zhì)發(fā)生泄漏咆繁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一顶籽、第九天 我趴在偏房一處隱蔽的房頂上張望玩般。 院中可真熱鬧,春花似錦礼饱、人聲如沸坏为。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匀伏。三九已至,卻和暖如春蝴韭,著一層夾襖步出監(jiān)牢的瞬間够颠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工榄鉴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留摧找,地道東北人核行。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓牢硅,卻偏偏與公主長得像蹬耘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子减余,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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

  • 從三月份找實習(xí)到現(xiàn)在综苔,面了一些公司,掛了不少位岔,但最終還是拿到小米如筛、百度、阿里抒抬、京東杨刨、新浪、CVTE擦剑、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,194評論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法妖胀,類相關(guān)的語法,內(nèi)部類的語法惠勒,繼承相關(guān)的語法赚抡,異常的語法,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • Java SE 基礎(chǔ): 封裝纠屋、繼承涂臣、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個獨立的整體,并盡...
    Jayden_Cao閱讀 2,099評論 0 8
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,500評論 3 93
  • 我想把生活過成一首詩售担。一首沒有幾個人知道的小詩赁遗。 就像現(xiàn)在的我喜歡料理。將來的生活我要每天做一次飯族铆,早上用微波爐做...
    喬果兒閱讀 534評論 0 2