天天看點

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

目錄

政策模式概念

政策模式使用案例

政策模式在開源架構中的應用

政策模式概念

  • 定義:定義了算法家族,分别封裝起來,讓他們之間可以互相調用,此模式讓算法的變化不會影響到使用算法的使用者。可以消除大量的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類,用作資源加載
設計模式 | 政策模式介紹、使用案例、開源架構應用

繼續閱讀