您的位置 首页 java

项目重构,我是如何优化大量屎一样的 if else 代码的?

目录:

  • if else
  • 策略模式
  • 1、首先抽象业务处理器
  • 2、将业务处理器和其支持处理的类型放到一个容器中,java里 Map 就是最常用的容器之一
  • 3、定义不同的处理器
  • 4、测试类

前段时间,我将公司系统中的批量审单的功能进行了重构,用到了java的并发编程进行异步化处理,数据库的乐观锁机制处理多线程并发更新数据。

其中批量审单的业务处理涉及到多种任务类型,对应不同的业务方法进行处理,比如 转仓 ,转快递,添加赠品,删除赠品,拆分订单,批量驳回,批量作废等等,其中就用到了策略模式。

if else

 if ("BATCH_CHANGE_WAREHOUSE".equals(task type )) {
 //批量转仓逻辑
 } 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 applicationContext Aware {

private Map chooseMap = new HashMap<>();

public InspectionSolver choose (String type) {

return chooseMap.get(type);

}

@PostConstruct

public void register () {

Map solverMap = context.getBeansOfType(InspectionSolver.class);

for (InspectionSolver solver : solverMap.values()) {

for (String support : solve r.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()方法了,目的达到。

End

作者:坚持就是胜利

来源:

文章来源:智云一二三科技

文章标题:项目重构,我是如何优化大量屎一样的 if else 代码的?

文章地址:https://www.zhihuclub.com/190771.shtml

关于作者: 智云科技

热门文章

网站地图