专栏首页用户5521492的专栏代码中太多 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()方法了,目的达到。

本文分享自微信公众号 - 一个优秀的废人(feiren_java),作者:一个优秀的废人

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java 基础(一)| 使用泛型的正确姿势

    为跳槽面试做准备,今天开始进入 Java 基础的复习。希望基础不好的同学看完这篇文章,能掌握泛型,而基础好的同学权当复习,希望看完这篇文章能够起一点你的青涩记忆...

    一个优秀的废人
  • 聊聊工作中常用的设计模式

    来 源:cnblogs.com/ILoke-Yang/p/8054466.html

    一个优秀的废人
  • SpringBoot | SpringBoot 是如何实现日志的?

    说到日志框架不得不说门面模式。门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用。用一张图来表示门面模式的结构为:

    一个优秀的废人
  • 业务代码中,太多 if else 怎么办?

    来源:juejin.im/post/5d12228de51d45775c73dd1b

    芋道源码
  • ReactJS分析之入口函数render

    前言   在使用React进行构建应用时,我们总会有一个步骤将组建或者虚拟DOM元素渲染到真实的DOM上,将任务交给浏览器,进而进行layout和paint等...

    欲休
  • SpringMVC @RequestMapping 注解

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    多凡
  • 看Ribbon源码增值的Archaius源码分析

    可以看输出结果,可以看到SampleBean的name属性已经发生变更了。name属性从Sample Bean变更到A Coffee Bean from Gau...

    用户2032165
  • Python|Google Python样式指南(2)

    条件表达式(有时称为“三元运算符”)是为if语句提供较短语法的机制。例如:x = 1 if cond else 2。

    算法与编程之美
  • spring boot集成WebSocket实时输出日志到web页面

    前言碎语 今天来做个有趣的东西,就是实时将系统日志输出的前端web页面,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot...

    kl博主
  • springboot2上报metrics到statsd

    micrometer-registry-statsd-1.0.1-sources.jar!/io/micrometer/statsd/StatsdFlavor....

    codecraft

扫码关注云+社区

领取腾讯云代金券