利用工厂模式+策略模式去掉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); }