华为 荣耀7,马烈松,音乐涂鸦乐园全集
在公司负责的就是订单取消业务,老系统中各种类型订单取消都是通过if else 判断不同的订单类型进行不同的逻辑。在经历老系统的折磨和产品需求的不断变更,决定进行一次大的重构:消灭 if else。
接下来就向大家介绍下是如何消灭 if else。
@service public class cancelorderservice { public void process(orderdto orderdto) { int servicetype = orderdto.getservicetype(); if (1 == servicetype) { system.out.println("取消即时订单"); } else if (2 == servicetype) { system.out.println("取消预约订单"); } else if (3 == servicetype) { system.out.println("取消拼车订单"); } } }
若干个月再来看就是这样的感觉
@service public class cancelorderstrategyservice { @autowired private strategycontext context; public void process(orderdto orderdto) { ordertypeenum ordertypeenum = ordertypeenum.getbycode(orderdto.getservicetype()); abstractstrategy strategy = context.getstrategy(ordertypeenum); strategy.process(orderdto); } }
简洁的有点过分了是不是!!!
下面选取了即时订单和预约订单的策略.
@service @ordertypeannotation(ordertype = ordertypeenum.instant) public class instantorderstrategy extends abstractstrategy { @override public void process(orderdto orderdto) { system.out.println("取消即时订单"); } }
@service @ordertypeannotation(ordertype = ordertypeenum.booking) public class bookingorderstrategy extends abstractstrategy { @override public void process(orderdto orderdto) { system.out.println("取消预约订单"); } }
public abstract class abstractstrategy { abstract public void process(orderdto orderdto); }
每个策略中增加了注解ordertypeannotation,以标注适用于不同类型的策略内容.
@target({elementtype.type}) @retention(retentionpolicy.runtime) @documented @inherited public @interface ordertypeannotation { ordertypeenum ordertype(); }
其中最为核心的为strategyprocessor 策略处理器类和strategycontext 策略上下文,
@component public class strategyprocessor implements beanfactorypostprocessor { private static final string strategy_package = "com.lujiahao.strategy"; @override public void postprocessbeanfactory(configurablelistablebeanfactory configurablelistablebeanfactory) throws beansexception { map<ordertypeenum, class> handlermap = maps.newhashmapwithexpectedsize(3); classscanner.scan(strategy_package, ordertypeannotation.class).foreach(clazz -> { ordertypeenum type = clazz.getannotation(ordertypeannotation.class).ordertype(); handlermap.put(type, clazz); }); strategycontext context = new strategycontext(handlermap); configurablelistablebeanfactory.registersingleton(strategycontext.class.getname(), context); } }
public class strategycontext { private map<ordertypeenum, class> strategymap; public strategycontext(map<ordertypeenum, class> strategymap) { this.strategymap = strategymap; } public abstractstrategy getstrategy(ordertypeenum ordertypeenum) { if (ordertypeenum == null) { throw new illegalargumentexception("not fond enum"); } if (collectionutils.isempty(strategymap)) { throw new illegalargumentexception("strategy map is empty,please check you strategy package path"); } class clazz = strategymap.get(ordertypeenum); if (clazz == null) { throw new illegalargumentexception("not fond strategy for type:" + ordertypeenum.getcode()); } return (abstractstrategy) springbeanutils.getbean(clazz); } }
我们使用了枚举作为map中的key,相信大家很少有人这样操作过,不过可以放心操作.通过下面两篇文章解答大家的疑问.
策略模式极大的减少if else等模板代码,在提升代码可读性的同时,也大大增加代码的灵活性,添加新的策略即可以满足业务需求.
本人在我司业务中对策略模式的应用得到了很好的验证,从此再也不用担心产品改需求.
用策略模式一时爽,一直用一直爽
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
浅析我对 String、StringBuilder、StringBuffer 的理解
使用IDEA搭建SSM框架的详细教程(spring + springMVC +MyBatis)
Springboot整合freemarker 404问题解决方案
引入mybatis-plus报 Invalid bound statement错误问题的解决方法
网友评论