利用工厂模式+策略模式去掉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);
}
posted @ 2020-01-17 10:17  陆伟  阅读(2407)  评论(0编辑  收藏  举报