通俗易懂系列 | 設計模式(五):策略模式

介紹

策略設計模式是行爲設計模式之一。當咱們爲特定任務使用多個算法時,使用策略模式,客戶端決定在運行時使用的實際實現。java

策略模式的最佳示例之一是Collections.sort()採用Comparator參數的方法。基於Comparator接口的不一樣實現,對象將以不一樣的方式進行排序。算法

實例

對於咱們的示例,咱們將嘗試實施一個簡單的購物車,咱們有兩種付款策略 - 使用信用卡或使用PayPal。設計模式

首先,咱們將爲咱們的策略模式示例建立接口,在咱們的例子中,支付金額做爲參數傳遞。
支付方式:PaymentStrategy.javaide

package com.journaldev.design.strategy;

public interface PaymentStrategy {

    public void pay(int amount);
}

如今咱們將不得不使用信用卡/借記卡或經過PayPal爲支付建立具體的算法實現。測試

信用卡付款:CreditCardStrategy.javathis

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");
    }

}

Paypal付款:PaypalStrategy.java翻譯

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.");
    }

}

如今咱們的策略模式示例算法準備好了。咱們能夠實施購物車和付款方式將須要輸入做爲付款策略。設計

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;
    }
    
}

ShoppingCart.javacode

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);
    }
}

請注意,購物車的付款方式須要付款算法做爲參數,而且不會將其做爲實例變量存儲在任何位置。orm

讓咱們用一個簡單的程序測試咱們的策略模式示例設置。

ShoppingCartTest.java

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

類圖

總結

  • 咱們可使用組合爲策略建立實例變量,但咱們應該避免這種狀況,由於咱們但願將特定策略應用於特定任務。在Collections.sort()和Arrays.sort()方法中遵循相同的方法,將比較器做爲參數。
  • 策略模式與狀態模式(State Pattern)很是類似。其中一個區別是Context包含狀態做爲實例變量,而且能夠有多個任務,其實現能夠依賴於狀態,而策略模式策略做爲參數傳遞給方法,上下文對象沒有任何變量來存儲它。
  • 當咱們爲特定任務提供多個算法時,策略模式頗有用,咱們但願咱們的應用程序能夠靈活地在運行時爲特定任務選擇任何算法。
  • 優勢:一、算法能夠自由切換。 二、避免使用多重條件判斷。 三、擴展性良好。
  • 缺點:一、策略類會增多。 二、全部策略類都須要對外暴露。
  • 主要解決:在有多種算法類似的狀況下,使用 if...else 所帶來的複雜和難以維護。
  • 什麼時候使用:一個系統有許多許多類,而區分它們的只是他們直接的行爲。
  • 如何解決:將這些算法封裝成一個一個的類,任意地替換。
  • 關鍵代碼:實現同一個接口。
  • 使用場景: 一、若是在一個系統裏面有許多類,它們之間的區別僅在於它們的行爲,那麼使用策略模式能夠動態地讓一個對象在許多行爲中選擇一種行爲。 二、一個系統須要動態地在幾種算法中選擇一種。 三、若是一個對象有不少的行爲,若是不用恰當的模式,這些行爲就只好使用多重的條件選擇語句來實現。
  • 注意事項:若是一個系統的策略多於四個,就須要考慮使用混合模式,解決策略類膨脹的問題。

這就是java中的Strategy Pattern,我但願你喜歡它。
翻譯於:strategy-design-pattern-in-java

相關文章
相關標籤/搜索