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

  • 终极手撕之架构大全:分布式+框架+微服务+性能优化 , 够不够?
  • 三次阿里凉凉后 , 15天封闭式复习 , 终于赶上了“腾讯”末班车
简单 if-else , 可以使用 卫语句 进行优化 。 但是在实际开发中 , 往往不是简单 if-else 结构 , 我们通常会不经意间写下如下代码:
回想起被 `if-else` 支配的恐惧,下定决心我要打倒 if - else文章插图
-------------------- 理想中的 if-else --------------------public void today() { if (isWeekend()) { System.out.println("玩游戏") } else {; System.out.println("上班!"); } }-------------------- 现实中的 if-else --------------------if (money >= 1000) { if (type == UserType.SILVER_VIP.getCode()) { System.out.println("白银会员 优惠50元"); result = money - 50; } else if (type == UserType.GOLD_VIP.getCode()) { System.out.println("黄金会员 8折"); result = money * 0.8; } else if (type == UserType.PLATINUM_VIP.getCode()) { System.out.println("白金会员 优惠50元 , 再打7折"); result = (money - 50) * 0.7; } else { System.out.println("普通会员 不打折"); result = money; } }//省略 n 个 if-else ......毫不夸张的说 , 我们都写过类似的代码 , 回想起被 if-else 支配的恐惧 , 我们常常无所下手 , 甚至不了了之 。
下面分享一下我在开发中遇到复杂的 if-else 语句“优雅处理”思路 。 如有不妥 , 欢迎大家一起交流学习 。
01 需求假设有这么一个需求:
一个电商系统 , 当用户消费满1000 金额 , 可以根据用户VIP等级 , 享受打折优惠 。
根据用户VIP等级 , 计算出用户最终的费用 。
  • 普通会员 不打折
  • 白银会员 优惠50元
  • 黄金会员 8折
  • 白金会员 优惠50元 , 再打7折
02 编码实现private static double getResult(long money, int type) { double result = money; if (money >= 1000) { if (type == UserType.SILVER_VIP.getCode()) { System.out.println("白银会员 优惠50元"); result = money - 50; } else if (type == UserType.GOLD_VIP.getCode()) { System.out.println("黄金会员 8折"); result = money * 0.8; } else if (type == UserType.PLATINUM_VIP.getCode()) { System.out.println("白金会员 优惠50元 , 再打7折"); result = (money - 50) * 0.7; } else { System.out.println("普通会员 不打折"); result = money; } } return result; }为了方便演示 , 代码上我进行了简单实现 , 但实际上 if - else 会进行复杂的逻辑计费 。从功能上来说 , 基本完成 , 但是对于我这种有代码洁癖的人来说 , 代码质量上不忍直视 。 我们开始着手 优化一下我们的第一版代码吧 。
03 思考看到如上代码 , 聪明的朋友首先想到的是 , 这不是典型的策略模式吗?
你可真是个机灵鬼 , 我们先尝试用策略模式来优化一下代码吧 。
04 策略模式(1)什么是策略模式?
可能有的朋友还不清楚 , 什么是策略模式 。 策略模式是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换 。
比如上述需求 , 有返利、有打折、有折上折等等 。 这些算法本身就是一种策略 。 并且这些算法可以相互替换的 , 比如今天我想让 白银会员优惠50 , 明天可以替换为 白银会员打9折 。
说了那么多 , 不如编码来得实在 。
(2)编码
public interface Strategy { // 计费方法 double compute(long money);}// 普通会员策略public class OrdinaryStrategy implements Strategy { @Override public double compute(long money) { System.out.println("普通会员 不打折"); return money; } }// 白银会员策略public class SilverStrategy implements Strategy { @Override public double compute(long money) { System.out.println("白银会员 优惠50元"); return money - 50; } }// 黄金会员策略public class GoldStrategy implements Strategy{ @Override public double compute(long money) { System.out.println("黄金会员 8折"); return money * 0.8; }}// 白金会员策略public class PlatinumStrategy implements Strategy { @Override public double compute(long money) { System.out.println("白金会员 优惠50元 , 再打7折"); return (money - 50) * 0.7; }}我们定义来一个 Strategy 接口 , 并且定义 四个子类 , 实现接口 。 在对应的 compute方法 实现自身策略的计费逻辑 。
private static double getResult(long money, int type) { double result = money; if (money >= 1000) { if (type == UserType.SILVER_VIP.getCode()) { result = new SilverStrategy().compute(money); } else if (type == UserType.GOLD_VIP.getCode()) { result = new GoldStrategy().compute(money); } else if (type == UserType.PLATINUM_VIP.getCode()) { result = new PlatinumStrategy().compute(money); } else { result = new OrdinaryStrategy().compute(money); } } return result;}然后对应 getResult 方法 , 根据 type 替换为对应的 用户VIP 策略 。这里代码上出现了重复的调用 compute, 我们可以尝试进一步优化 。