回想起被 `if-else` 支配的恐惧,下定决心我要打倒 if - else( 二 )


private static double getResult(long money, int type) { if (money < 1000) { return money; } Strategy strategy; if (type == UserType.SILVER_VIP.getCode()) { strategy = new SilverStrategy(); } else if (type == UserType.GOLD_VIP.getCode()) { strategy = new GoldStrategy(); } else if (type == UserType.PLATINUM_VIP.getCode()) { strategy = new PlatinumStrategy(); } else { strategy = new OrdinaryStrategy(); } return strategy.compute(money);} 还记得我在第一篇中说到的卫语句吗? 我们在这里把 money < 1000 的情况提前 return 。 更关注于满1000逻辑 ,也可以减少不必要的缩进 。
05 深思我曾一度 以为 策略模式不过如此 。 以为代码优化到这已经可以了 。
但是还有一个恐怖的事情 , if-else 依然存在 :)
我尝试翻阅了许多书籍 , 查看如何消除 策略模式中的 if-else
书中大部分的方法是 , 使用简单工厂 + 策略模式 。 把 if - else 切换为 switch 创建一个工厂方法而已 。
但是这远远没有达到我想要的效果 , 打倒 if - else
直到某一天夜里 , 我大佬在群里分享一个 Java8 小技巧时 , 从此大开新世界 。
06 工厂 + 策略public interface Strategy { double compute(long money); // 返回 type int getType();}public class OrdinaryStrategy implements Strategy { @Override public double compute(long money) { System.out.println("普通会员 不打折"); return money; } // 添加 type 返回 @Override public int getType() { return UserType.SILVER_VIP.getCode(); }}public class SilverStrategy implements Strategy { @Override public double compute(long money) { System.out.println("白银会员 优惠50元"); return money - 50; } // type 返回 @Override public int getType() { return UserType.SILVER_VIP.getCode(); }}....省略剩下 Strategy我们先在 Strategy 新增一个 getType 方法 , 用来标示 该策略的 type 值 。 代码相对简单 , 这里就不过多介绍了
public class StrategyFactory { private Map map; public StrategyFactory() { List strategies = new ArrayList<>(); strategies.add(new OrdinaryStrategy()); strategies.add(new SilverStrategy()); strategies.add(new GoldStrategy()); strategies.add(new PlatinumStrategy()); strategies.add(new PlatinumStrategy()); // 看这里 看这里 看这里! 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); }} 静态内部类单例 , 单例模式实现的一种 , 不是本文重点 , 如不了解 , 可以自行 google
我们再着手创建一个 StrategyFactory 工厂类 。 StrategyFactory 这里我使用的是静态内部类单例 , 在构造方法的时候 , 初始化好 需要的 Strategy , 并把 list 转化为 map 。这里 转化就是“灵魂”所在 。
(1)toMap
我们先来看看 Java8 语法中的小技巧 。
通常情况下 , 我们遍历 List , 手动put到 Map 中 。
-------------- before ----------------- map = new HashMap<>();for (Strategy strategy : strategies) { map.put(strategy.getType(), strategy);}-------------- after Java8 -----------------map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));(2)效果
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);}至此 , 通过一个工厂类 , 在我们在 getResult()调用的时候 , 根据传入 type , 即可获取到 对应 Strategy
再也没有可怕的 if-else 语句 。
07 后续后续代码优化上 , 若是 Java 项目 , 可以尝试使用自定义注解 , 注解 Strategy 实现类 。
这样可以简化原来需在工厂类 List 添加一个 Stratey 策略 。
最后以上就是我在开发中遇到复杂的 if-else 语句“优雅处理”思路 , 如有不妥 , 欢迎大家一起交流学习 。
【回想起被 `if-else` 支配的恐惧,下定决心我要打倒 if - else】作者:hyzhan43原文链接: