設計模式 | 策略模式介紹、使用案例、開源框架應用

目錄

策略模式概念

策略模式使用案例

策略模式在開源框架中的應用


策略模式概念

  • 定義:定義了算法家族,分別封裝起來,讓他們之間可以相互調用,此模式讓算法的變化不會影響到使用算法的用戶。可以消除大量的if-else代碼
  • 適用場景:系統有很多類,而它們的區別僅僅在於他們的行爲不同;一個系統需要動態的在幾種算法中選擇一種。
  • 優點:符合開閉原則;避免了使用多重條件轉移語句;確保算法的保密性和安全性;
  • 缺點:客戶端必須知道所有的策略類,並且自行決定使用哪一個策略類;新增很多類;

策略模式使用案例

以電商系統的折扣模型來演示策略模式,淘淘購物網的活動折扣包含滿減、返現、立減等。在使用策略模式前需要很多if-else代碼來做優惠券類型判斷,以做出扣減。使用策略模式的代碼如下:

創建一個折扣父接口,它有一個打折方法

public interface PromotiionStrategy {
    void doPromotion();
}

創建具體活動類,繼承父接口

//返現活動類
public class FanxianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("返現促銷,返回的金額存放到慕課網賬戶餘額中");
    }
}

//立減活動類
public class LijianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("立減促銷,課程價格直接減去促銷價格");
    }
}

//滿減活動類
public class ManjianPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("滿減促銷,滿200減20元");

    }
}

//不參與活動類
public class NonPromotiionStrategy implements PromotiionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("無優惠");
    }
}

創建活動調用類,關聯折扣父接口,executePromotiionStrategy方法調用父接口的打折方法。

public class PromotionActivity {
    public PromotionActivity(PromotiionStrategy promotiionStrategy) {
        this.promotiionStrategy = promotiionStrategy;
    }
    private PromotiionStrategy promotiionStrategy;
    public void executePromotiionStrategy(){
        promotiionStrategy.doPromotion();
    }

}

創建測試類

 public static void main(String[] args) {
        String type = "lijian";
        PromotionActivity promotionActivity = null;
        if(type.equals("lijian")){
            promotionActivity = new PromotionActivity(new LijianPromotiionStrategy());

        }else if(type.equals("manjian")){
            promotionActivity = new PromotionActivity(new ManjianPromotiionStrategy());

        }else if(type.equals("fanxian")){
            promotionActivity = new PromotionActivity(new FanxianPromotiionStrategy());

        }
        promotionActivity.executePromotiionStrategy();

    }

輸出:立減促銷,課程價格直接減去促銷價格

可以看到使用了策略模式後減少了在扣減時的if-else判斷,但是在類型判斷時仍然有if-else判斷,所以在使用策略模式時推薦搭配工廠模式,具體實現如下

新增策略工廠類

public class PromotiionStrategyFactory {
    private static Map<String,PromotiionStrategy> MAP_INFO = new HashMap<>();
    public static String LIJIAN_KEY = "lijian";
    public static String MANJIAN_KEY = "manjian";
    public static String FANXIAN_KEY = "fanxian";

    static {
        MAP_INFO.put(LIJIAN_KEY,new LijianPromotiionStrategy());
        MAP_INFO.put(MANJIAN_KEY,new ManjianPromotiionStrategy());
        MAP_INFO.put(FANXIAN_KEY,new FanxianPromotiionStrategy());

    }
    private static final PromotiionStrategy NON_PROMOTION = new NonPromotiionStrategy();

    public PromotiionStrategyFactory() {
    }
    public static PromotiionStrategy getPromotiionStrategy(String key){
        PromotiionStrategy result = MAP_INFO.get(key);
        return  result == null ? NON_PROMOTION:result;
    }

}

新建測試方法

 public static void main(String[] args) {
        String type = "manjian";
        PromotionActivity promotionActivity = new PromotionActivity(PromotiionStrategyFactory.getPromotiionStrategy(type));
        promotionActivity.executePromotiionStrategy();

    }

打印輸出:滿減促銷,滿200減20元

可以看到使用了策略模式後邏輯變得很清晰,且很容易拓展。如果想拓展一種新的促銷時客戶端只需要在調用打折方法時同時傳入約定好的類型即可,後段處理邏輯中新增一個促銷類,並完善工廠方法的類型池。符合開閉原則。

類圖如下:

策略模式在開源框架中的應用

  • spring框架中的InstantiationStrategy類,用作類實例化
  • org.springframework.core.io.Resource類,用作資源加載

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章