内容简介:前段时间,我将公司系统中的批量审单的功能进行了重构,用到了java的并发编程进行异步化处理,数据库的乐观锁机制处理多线程并发更新数据。其中批量审单的业务处理涉及到多种任务类型,对应不同的业务方法进行处理,比如转仓,转快递,添加赠品,删除赠品,拆分订单,批量驳回,批量作废等等,其中就用到了策略模式。看起来,思路清晰,if,else分支也很清楚,但不觉得代码很臃肿,维护起来麻烦吗,尤其是其他人来接锅的时候,连看下去的欲望都没有了。这时候你需要用策略模式消除其中的if else,进行一下简单的重构!这里是在应用启
前段时间,我将公司系统中的批量审单的功能进行了重构,用到了 java 的并发编程进行异步化处理,数据库的乐观锁机制处理多线程并发更新数据。其中批量审单的业务处理涉及到多种任务类型,对应不同的业务方法进行处理,比如转仓,转快递,添加赠品,删除赠品,拆分订单,批量驳回,批量作废等等,其中就用到了策略模式。
if else模式
if ("BATCH_CHANGE_WAREHOUSE".equals(taskType)) { //批量转仓逻辑 } else if ("BATCH_CHANGE_SHIPPING".equals(taskType)) { //批量转快递逻辑 } else if ("BATCH_REPLACE_ORDER_GOODS".equals(taskType)) { //批量替换订单商品逻辑 } else if ("BATCH_DELETE_ORDER_GOODS".equals(taskType)) { //批量删除订单商品逻辑 } else if ("BATCH_ADD_MEMO".equals(taskType)) { //批量添加备注逻辑 } else { //任务类型未知 System.out.println("任务类型无法处理"); } 复制代码
看起来,思路清晰,if,else分支也很清楚,但不觉得代码很臃肿,维护起来麻烦吗,尤其是其他人来接锅的时候,连看下去的欲望都没有了。这时候你需要用策略模式消除其中的if else,进行一下简单的重构!
策略模式
1、首先抽象业务处理器
public abstract class InspectionSolver { public abstract void solve(Long orderId, Long userId); public abstract String[] supports(); } 复制代码
2、将业务处理器和其支持处理的类型放到一个容器中,java里Map就是最常用的容器之一
@Component public class InspectionSolverChooser implements ApplicationContextAware{ private Map<String, InspectionSolver> chooseMap = new HashMap<>(); public InspectionSolver choose(String type) { return chooseMap.get(type); } @PostConstruct public void register() { Map<String, InspectionSolver> solverMap = context.getBeansOfType(InspectionSolver.class); for (InspectionSolver solver : solverMap.values()) { for (String support : solver.supports()) { chooseMap.put(support,solver); } } } private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.context=applicationContext; } } 复制代码
这里是在应用启动的时候,加载spring容器中所有InspectionSolver类型的处理器,放到InspectionSolverChooser的map容器中。注意是InspectionSolver类型,所以定义的处理器都得继承InspectionSolver,其次是spring容器中的才能加载,所以定义的处理器都得放到spring容器中(@Component注解不能少)
3、定义不同的处理器
@Component public class ChangeWarehouseSolver extends InspectionSolver { @Override public void solve(Long orderId, Long userId) { System.out.println("订单"+orderId+"开始进行批量转仓了。。"); } @Override public String[] supports() { return new String[] {InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE}; } } @Component public class ChangeShippingSolver extends InspectionSolver{ @Override public void solve(Long orderId, Long userId) { System.out.println("订单"+orderId+"开始进行转快递了。。"); } @Override public String[] supports() { return new String[] {InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_SHIPPING}; } } @Component public class ReplaceOrderGoodsSolver extends InspectionSolver{ @Override public void solve(Long orderId, Long userId) { System.out.println("订单"+orderId+"开始进行替换商品了"); } @Override public String[] supports() { return new String[]{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_REPLACE_ORDER_GOODS}; } } 复制代码
4、测试类
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes=Application.class)// 指定spring-boot的启动类 public class InspectionTest { @Autowired private InspectionSolverChooser chooser; @Test public void test() throws Exception{ //准备数据 String taskType = InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE; Long orderId = 12345L; Long userId = 123L; //获取任务类型对应的solver InspectionSolver solver = chooser.choose(taskType); if (solver == null) { throw new RuntimeException("任务类型暂时无法处理!"); } //调用不同solver的方法进行处理 solver.solve(orderId,userId); } } 复制代码
在测试类中我消除了可能一长段的if else,从选择器InspectionSolverChooser中根据type的不同取出不同的任务处理器InspectionSolver,然后调用其solve()方法进行任务处理,不同处理器调用的当然就是不同的solve()方法了,目的达到。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- R中用线性回归进行预测建模
- 在Markdown中用mermaid语法绘制图表
- iOS面试题·项目中用过 Runtime 吗?
- 在docker中用Tomcat运行web项目
- 在项目实践中用更优雅的方式处理数组问题
- ajax中用josnp接收josn数据的实现方法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。