設計模式之---策略模式

策略模式其實一直在用,只是你不知道你用的 就是策略模式。

是面向接口編程的典型設計模式。

該模式可以解決在不同算法實現時使用if..else帶來的複雜和難以維護,完全實現接口該詞的理念,無縫插拔,降低耦合度。


模擬場景、問題提出

假設現在有一個場景,雙十一賣書促銷,普通遊客打98折,會員打9折,plus會員打8折。那最簡單的寫法如下:

public class Price {

    public double price(String userType, double productPrice) {
        if ("遊客".equals(userType)) {
            return productPrice * 0.98;
        } else if ("會員".equals(userType)) {
            return productPrice * 0.9;
        } else if ("plus會員".equals(userType)) {
            return productPrice * 0.8;
        }
        return productPrice;
    }
}

但這樣會帶來什麼問題?

  1. 該方法一大坨代碼摻雜了太多種類的計算方式,稍不留神就會出錯;
  2. 過多的if..else使代碼難以維護;
  3. 若有折扣變動或用戶種類增多,會使本就一大坨的代碼變成更大的一坨;且需要修改已有的代碼,造成未知錯誤。

 

引入策略模式

策略模式可以有效解決上述問題,做到易維護、可擴展。

策略模式定義:

定義一系列的算法,把他們一個個封裝起來,並且使他們可相互替換。

爲了使價格計算方式算法獨立於用戶類型 ,需要專門有一個上下文類Context持有算法,但不決定使用哪個算法,將決定權交於用戶;由用戶選擇好具體算法後,設置到上下文中;當用戶通知上下文執行功能時,即根據選擇執行具體的算法。

這樣可以使用戶與具體算法分離

  • 算法可獨立於用戶變化
  • 用戶可動態切換需要使用的算法

 

策略模式實例代碼

下面我將創建一個Strategy接口,然後分別用3個類使用不同的算法實現該接口中的price(計算價格)方法;然後Context類是一個上下文類,調用他的某個參數決定其使用哪個策略;最終通過Test類根據不同的入參調用策略類得到不同的策略執行結果。

首先創建Strategy接口,該接口只有一個方法price():

/**
 * 策略接口
 */
public interface Strategy {

    /**
     * 計算價格
     */
    public double price(double productPrice);
}

然後創建3個類實現該接口,並用不同的算法實現price()方法,分別代表三類用戶,返回不同的折扣結果,若調用則會輸出不同的運行結果:

/**
 * 普通遊客
 */
public class StrategyNormalUser implements Strategy {

    @Override
    public double price(double productPrice) {
        return productPrice * 0.98;
    }
}
/**
 * vip用戶
 */
public class StrategyVipUser implements Strategy {

    @Override
    public double price(double productPrice) {
        return productPrice * 0.9;
    }
}
/**
 * plus_vip用戶
 */
public class StrategyPlusVipUser implements Strategy {

    @Override
    public double price(double productPrice) {
        return productPrice * 0.8;
    }
}

新建一個Context類,引入strategy變量,並新增contextExecute方法,該方法會調用Strategy接口中的price()方法

/**
 * 上下文類
 */
public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public double contextExecute(double productPrice) {
        return this.strategy.price(productPrice);
    }
}

開始測試,在Test類中調用Context的構造方法,直接將不同的Strategy子類給strategy賦值,然後調用contextExecute方法,內部繼續調用子類的price方法,得到不同的運算結果。當想更換用戶時,只需要在12行創建Strategy策略對象時,將不同的子類傳入構造器,就改這一行,是不是 簡單清晰?

/**
 * 測試類
 */
public class Test {

    // 原始價格
    final static double PRODUCT_PRICE = 100.00;

    public static void main(String[] args) {

        // 1、選擇並創建需要使用的策略對象
        Strategy strategy = new StrategyNormalUser();
//        Strategy strategy = new StrategyVipUser();
//        Strategy strategy = new StrategyPlusVipUser();

        // 2、創建上下文對象
        Context context = new Context(strategy);

        // 3、計算價格
        System.out.println("折扣後的價格爲:" + context.contextExecute(PRODUCT_PRICE));
    }
}

 運行結果:

 

上述操作流程圖: 

 

 

 

發佈了43 篇原創文章 · 獲贊 54 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章