代码优化之非核心代码的抽取问题

26 篇文章 0 订阅

代码优化之非核心代码的抽取问题

背景

为什么需要代码抽取非核心代码

随着版本的迭代和不同开发人员对接口的修改,通常以不改动老代码为原则进行微调,随着微调的积累,就逐渐产生非核心代码没有得到归纳梳理的情况。

非核心代码对原业务代码的影响

1,如果controller层出现非常大篇幅的逻辑判断,导致controller类代码行数非常大,定位问题的时候需要从接口一直往下寻找对应的service调用
2,如果是service出现大篇幅的逻辑判断,很容易跟原来的业务逻辑混淆,在定位的问题的时候,需要仔细阅读,另外在新增需求的时候,比较担心在大篇幅的逻辑里是否存在也对相对应的功能进行修改了,需要阅读检查,或者就干脆不混在原来代码中间增加逻辑,直接在后面继续逻辑处理,也就可能出现了再次多于的查表和修改表的问题发生。

处理方案:

私有方法抽取

这个大家都熟悉,pass

MiddleHandle处理类

算是私有方法的独立处理,中间的处理类并不是必须的,如果非核心的业务逻辑代码不是很多,其实可以不用独立处理,并且中间处理类其实还需要考虑到返回值的判断,中间类无法实现直接对中间类进行return返回响应等问题。如果controller非常大或者service非常大,中间处理类就很有必要。
例子:入参数据的检查抽取

这个controller存在100行的数据检查,抽取后美观了很多,而且比较容易虚招到核心的service调用。

类内聚

我觉得这个是一时使用一时爽,一直使用一直爽的方法,这个方法大家都懂,只是使用习惯问题。
类内聚可以结合数据封装和业务分离的概念来理解,最重要的功能是做数据封装,也可以做非核心业务抽取。
注意问题:
类内聚的方法名尽量避开get和set开头,如果需要使用get和set,则后面的英文不要与字段名相同。
尽量不采用原实体类(非必要情况),尽量才作用dto类进行数据拷贝后,再进行类内聚
例子:入参的数据准确性校验(非核心业务逻辑抽取)

数据封装和业务分离

我觉得这个是容易被忽视的一个问题,这里不关心封装的手段是封装到service的私有方法还是类内聚或者独立的middleHandle处理类,只涉及抽取的原则。
经常能遇到两个场景,一个是自己的代码在测试期间发现有点不美观了,另外一个是在别人的代码里增加自己的需求,而且这个需求影响面比较大,修改错地方可能造成无法预计的后果。这里说第二个场景。
如果可以在原来的代码上直接新增代码,建议先完成功能开发。如果是代码太多了梳理之后还是无从下手,就直接开整。(涉及到修改别人的代码,搬动前先沟通)
先对代码进行归类,重新标注注释(标记的注释有利于拆分和抽取代码用),然后对于同类功能属性的代码进行位置上的迁移调整,最后对每个模块进行分离。
第一步,加注释

第二步,确定是否存在数据库的查询,存在数据库查找,要么是按照查找前查找后区分,要么新增私有方法进行一次抽取,下面是存在数据检查,封装数据,查库,就需要考虑是否有必要改动代码。

第三步,考虑原来的封装方法是否进行重组。一般情况下可以不用重组。
第四步,考虑使用私有方法,数据处理类,类内聚等方式进行拆分。
(经常遇到代码中存在注释掉的代码,如果看年代是去年的,不删掉就留着下一位阅读)
(对于if else封装很长代码的,能去掉就去掉,不能去掉也要拆,实在不能拆,给个换行,idea才能收起代码块)
(代码重构后变动可能比较大,建议修改前备份,或者预留原来的接口,注释好修改时间和过期时间)
例子:通过StandarProductBaseInfoServiceMiddleHandle类和私有方法抽取将数据检查,数据封装和数据修改操作分开

复杂逻辑采用中间变量,减少数据库的操作次数

当存在某个业务逻辑需要再次操作数据库的时候,可以考虑采用中间变量,将数据操作合并到数据操作模块中

提取代码里的对象进行共享。

大逻辑代码拆解思路:

可分三大方向
1.数据检验(检查和数据验证),此处也可以分几个小方向拆解(数据检查一部分,数据验证一部分)
2.数据封装(包含部分关键数据验证,重要数据的封装),此处可根据实际业务可拆分多个处理方法,尽量业务独立开,让业务与代码相紧合,不相干业务可进行松耦合模式处理,让后期开发人员再开发某一快业务时,只关心其相关业务代码块,
可重用而且复用比较高的可整成相关模板方法或者工具类,还有思路不要把所有业务逻辑代码都往一个service逻辑层去装,做到相应业务逻辑交给相应service处理层
3.数据保存和异步日志(可把数据同步和异步的进行拆分,保证一个事务之间数据的一致性,如跟异步数据有紧密相关的,尽量做到数据一致性,把异步放在最后一步操作与手动回滚机制)

复杂的if else结构,转用私有方法return来处理

下面例子如果是直接书写到与match对象同级,将会导致不断判断非空,然后执行下一步,最终会导致非常多的if else结构嵌套

if(CollectionUtils.isNotEmpty(list)) {
    //其他的if else结构
} else {
    
}

所以采用私有方法就能对else进行提前返回。

        if (CollectionUtils.isEmpty(textureSKUList)) {
            match.canNotMatch();
            return ;
        }
        if (Objects.nonNull(in.getWageCraftId())) {
            textureSKUList = textureSKUList.stream().filter(x->x.getWageCraftId().equals(in.getWageCraftId())).collect(Collectors.toList());
        } else {
            match.setWageCraftMatching(MatchingResults.MATCH_NULL);
        }
        if (CollectionUtils.isEmpty(textureSKUList)) {
            match.setWageCraftMatching(MatchingResults.MATCH_NO);
            return ;
        }
        match.setWageCraftMatching(MatchingResults.MATCH_YES);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值