一步步降低代码复杂度
Table of Contents1 Sonar认知复杂度计算规则2 降低复杂度2.1 降低复杂度前的准备2.2 一个for循环只做一件事2.3 减少for循环中的if else、continue2.4 抽离try/catch2.5 for循环内容不宜过长2.6 验证重构3. 通过idea一秒钟实现重构1 Sonar认知复杂度计算规则这里的认知复杂...
Table of Contents
1 Sonar认知复杂度计算规则
这里的认知复杂度特指代码分析工具Sonar的认知复杂度。
Sonar要求认知复杂度低于15。首先了解一下认知复杂度的计算规则。
|
来看两个官方示例
2 降低复杂度
了解了复杂度的规则,我们的主要工作就是围绕着如何优雅的减少条件判断来进行。
这里以某方法 restrictionNumLimit 为例展示降低复杂度的若干步骤。
Sonar扫描显示该方法的复杂度为20
restrictionNumLimit逻辑为判断当前下单的商品数量是否超过限购。
2.1 降低复杂度前的准备
首先为restrictionNumLimit编写单元测试,覆盖各个条件边界。
为此编写了一个代码行数5倍于restrictionNumLimit的单元测试,重构前测试全绿。
没有单元测试的重构如同盲人开车,不翻车看运气。
2.2 一个for循环只做一件事
查看代码,for循环里面有if else。逻辑为根据商品Id累加商品数量。
if else,加上for循环,总共贡献了3个复杂度。
|
借助 java.util.Collection.stream 、java.util.Map.compute ,在一个表达式里面实现了商品数量的累加,抹除了for循环与if else的认知复杂度。
|
2.3 减少for循环中的if else、continue
for循环中的continue,if括号内过长的条件判断都增加了复杂度。
由于continue跟业务处理无关,先在外围通过java.util.stream.Stream.filter把continue从for循环抽离出去,把过长的条件判断抽取到一个方法内。
如下,for循环中已经没有continue跟过长的条件判断。
2.4 抽离try/catch
try/catch代码块丑陋不堪。它们搞乱了代码结构,把错误处理与正常流程混为一谈。最好把try和catch代码块的主体部分抽离出来,另外形成函数。
——《代码整洁之道》
通过把for循环里面的try方法抽取到单独的方法,继续降低复杂度
|
2.5 for循环内容不宜过长
如果一个for循环内容过长只会越来越长。
如下当满足条件:该商品历史购买数量已经超过限购直接就跳出for循环return了,那么return后面的else可以省略。
同时else里面的内容可以抽取到一个方法里面,避免for循环内容过长。
2.6 验证重构
所谓重构(refactoring)是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。
——《重构:改善既有代码的设计》
重构后要保证代码逻辑的正确,如下重构后测试继续全绿。
3. 通过idea一秒钟实现重构
如果一个工具能够为你安全地提取方法,你就不需要自己编写测试去验证提取是否正确。
——《修改代码的艺术》
有时候我们来不及为一个方法写一个超长的单元测试,借助idea的Extract Method功能瞬间完成重构,降低认知复杂度。
如下选中超长的条件判断,右键Refactor,选中Extract Method,然后给抽取的方法起一个新的名字。
更多推荐
所有评论(0)