利用工廠模式+策略模式去掉if-else


需求:

假設有這么一個需求:

一個電商系統,當用戶消費滿1000 金額,可以根據用戶VIP等級,享受打折優惠。根據用戶VIP等級,計算出用戶最終的費用。

  • 普通會員 不打折
  • 白銀會員 優惠50元
  • 黃金會員 8折
  • 白金會員 優惠50元,再打7折
 1 private static double getResult(long money, int type) {
 2 
 3     double result = money;
 4 
 5     if (money >= 1000) {
 6         if (type == UserType.SILVER_VIP.getCode()) {
 7 
 8             System.out.println("白銀會員 優惠50元");
 9             result = money - 50;
10         } else if (type == UserType.GOLD_VIP.getCode()) {
11 
12             System.out.println("黃金會員 8折");
13             result = money * 0.8;
14         } else if (type == UserType.PLATINUM_VIP.getCode()) {
15 
16             System.out.println("白金會員 優惠50元,再打7折");
17             result = (money - 50) * 0.7;
18         } else {
19             System.out.println("普通會員 不打折");
20             result = money;
21         }
22     }
23 
24     return result;
25 }

工廠+策略

 1 public interface Strategy {
 2 
 3     double compute(long money);
 4 
 5     // 返回 type
 6     int getType();
 7 }
 8 
 9 
10 public class OrdinaryStrategy implements Strategy {
11 
12     @Override
13     public double compute(long money) {
14         System.out.println("普通會員 不打折");
15         return money;
16     }
17 
18     // 添加 type 返回
19     @Override
20     public int getType() {
21         return UserType.SILVER_VIP.getCode();
22     }
23 }
24 
25 public class SilverStrategy implements Strategy {
26 
27     @Override
28     public double compute(long money) {
29 
30         System.out.println("白銀會員 優惠50元");
31         return money - 50;
32     }
33 
34     // type 返回,表示該策略的type值
35     @Override
36     public int getType() {
37         return UserType.SILVER_VIP.getCode();
38     }
39 }
40 
41 ....省略剩下 Strategy

工廠類:

public class StrategyFactory {

    private Map<Integer, Strategy> map;

    public StrategyFactory() {

        List<Strategy> strategies = new ArrayList<>();

        strategies.add(new OrdinaryStrategy());
        strategies.add(new SilverStrategy());
        strategies.add(new GoldStrategy());
        strategies.add(new PlatinumStrategy());
        strategies.add(new PlatinumStrategy());

        // 看這里 看這里 看這里!  collect收集,把strategies的流的值都收集起來,轉換成Map<key,value>
        map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));

        /* 等同上面
        map = new HashMap<>();
        for (Strategy strategy : strategies) {
            map.put(strategy.getType(), strategy);
        }*/
    }
    
    public static class Holder {
        public static StrategyFactory instance = new StrategyFactory();
    }

    public static StrategyFactory getInstance() {
        return Holder.instance;
    }

    public Strategy get(Integer type) {
        return map.get(type);
    }
}

這里用到了靜態內部類去實現單例模式。

寫法:

 1 package com.iot.api.design.singleton;
 2 
 3 /**
 4  * @ProjectName: smartdata
 5  * @Package: com.iot.api.design.singleton
 6  * @ClassName: Singleton
 7  * @Author: heluwei
 8  * @Description: 靜態內部類完成 單例模式
 9  * @Date: 2020/1/16 17:49
10  * @Version: 1.0
11  */
12  public class Singleton {
13     //1:構造器
14     private Singleton(){}
15     //2:利用靜態內部類去創建類。
16     private static class SingletonInstance{
17         private static final Singleton INSTANCE = new Singleton();
18     }
19     //3:別人調用
20     public static Singleton getInstance(){
21         return SingletonInstance.INSTANCE;
22     }
23 }

 

效果:

private static double getResult(long money, int type) {

    if (money < 1000) {
        return money;
    }

    Strategy strategy = StrategyFactory.getInstance().get(type);

    if (strategy == null){
        throw new IllegalArgumentException("please input right type");
    }

    return strategy.compute(money);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM