if-else语句太多了?我用设计模式消除了if-else
我在之前的文章中使用枚举消除了if-else语句 , 有兴趣的可以看看我的这篇文章:
“
如何用枚举消除if/else?-枚举高阶用法
”
这次我采用其他方式消除if-else 。
背景你在平时开发中肯定有使用if-else语句的时候 , 然而大量的if-else语句不利于代码阅读 , 影响代码复杂度 。 反正我在消除Sonar异味的时候头疼过 。
之前公司系统的代码中也存在if-else过多问题 , 导致代码不优雅 , 这里为了讲解 , 我将业务逻辑简化 。
假如我有一个计算实际价格的方法 , 要求输入用户的级别和商品的实际价格 , 返回商品的真实价格 , 代码如下:
文章插图
这里level就是用户的级别 , originalPrice就是商品的原始价格 。 如果用户级别为"normal" , 返回的真实价格为原始价格乘以1.0 。 如果用户级别为"vip" , 返回的真实价格为原始价格乘以0.9 。 否则返回原始价格 。
测试代码如下:
文章插图
结果"vip"的价格为:
getActualPrice()测试的真实价格为:90.0
上面的代码你可能看着没毛病 , 但是用户的等级可能还有超级vip(svip) , 还可能有ssvip 。 还可能更多 , 那么这个方法if-else将会非常多 。 并且会经常修改这个方法 , 违背了设计原则中的开闭原则 。 为此 , 我思考能不能不修改这个方法也能实现level级别的扩展呢 。
文章插图
使用设计模式消除if-else想来想去 , 我决定使用设计模式来消除if-else 。
CalculateStrategypublic interface CalculateStrategy {String userLevel();BigDecimal discount(BigDecimal originalPrice);}
这里先写一个计算的接口 , 定义了两个方法:获取用户等级 , 和相应价格计算的方法 。
NormalStrategy@Componentpublic class NormalStrategy implements CalculateStrategy {@Overridepublic String userLevel() {return "normal";}@Overridepublic BigDecimal discount(BigDecimal originalPrice) {return originalPrice.multiply(new BigDecimal("1.0"));}}
normal级别的实现类 。
@Componentpublic class VipStrategy implements CalculateStrategy {@Overridepublic String userLevel() {return "vip";}@Overridepublic BigDecimal discount(BigDecimal originalPrice) {return originalPrice.multiply(new BigDecimal("0.9"));}}
vip级别的实现类 。
我们计算真实价格的代码如下:
文章插图
这里我创建了一个map , map的key存放用户级别level , value存放CalculateStrategy的对象 。 当系统启动时 , IoC容器会给SaleService创建对象 , 这时map会存入所有实现了CalculateStrategy的对象 。
文章插图
然后编写一个getActualPriceWithStrategy()方法 , 用于根据用户级别计算商品实际价格 。 如果增加用户级别 , 只需要增加相应的类 , 如:SvipStrategy、SSvipStrategy等 。 这样 就不用修改getActualPriceWithStrategy()中的内容了 , 保证了这个方法的安全性 。
测试代码如下:
文章插图
推荐阅读
- 发布5年多了:Win10依然可以免费升级
- iPhone11说降就降,狂降1200元,网友:比12香多了
- 华为新发布两块“智慧屏”,人机交互的玩法更多了
- 实践中如何优化MySQL(建议收藏!)
- 留给哈啰的时间不多了
- 小多了!黑色版索尼PS5曝光,果然黑色更显瘦
- 正确使用#include语句的双引号形式和角括号形式
- 如果张三把服务器砸了,“双十一”是不是就可以逃单啦?不好意思他可能想多了......
- 美国无法阻止我们买顶级光刻机?想多了,能买到的是个“低配版”
- 马云退休1年多了,他曾花“天价”打造的蚂蚁森林,如今咋样了?