下面的类是一个老系统的代码,现在放到sonar上面进行扫描,扫出来的结果发现复杂度超过了30。
代码复杂度是指代码中的分支数量,比如有一个if分支,代码复杂度就加1,如果if中有“||”或者“&&”那么代码复杂度就加2,for和while同理。一般复杂度超过10的类就算是比较复杂的了,而这个类的复杂度竟然达到了30,代码的糟糕程度可见一斑,现在我们就来重构一下这个类的代码。
原始文件在这里。
重构开始吧!
多处String类型非空判断
1 2 3 4 5 6 |
|
重构之后:
1 2 3 4 5 6 7 8 9 10 11 |
|
原代码中不止这3个参数的校验,还有很多,越多参数的校验,我们重构后的复杂度就会越低。
代码复杂度变化:原来是3,修改后为1。
多String值判断
1 2 3 |
|
重构之后:
1 2 3 4 5 6 7 8 9 |
|
代码复杂度变化:原来是4,修改后为1。
对list的非空判断
1 2 |
|
重构之后:
1 2 3 4 5 6 7 |
|
代码复杂度变化:原来是2,修改后为1。
多个catch的内容相同
1 2 3 4 5 6 7 8 |
|
重构之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
代码复杂度变化:原来是2,修改后为1。
if判断结果复杂化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
重构之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
代码复杂度变化:原来是4,修改后为3。
本地变量始终不为null
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
重构之后:
1 2 3 4 5 6 7 8 9 10 11 |
|
代码复杂度变化:原来是1,修改后为0。
读取IO流的方法,为什么要自己实现?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
在原代码里面自己实现了一个对读取IO流字节的方法,这个可以使用apache-io或者guava的API代替:
1 2 3 4 |
|
代码复杂度变化:原来是很多,修改后为0。
最终重构后的版本见这里,最后的代码复杂度从原来的30降到了3。
代码写的比较仓促,没有写单元测试,其实最好的做法是在重构之前先写好单元测试,然后再慢慢修改原来的代码,每修改一处地方跑一遍单元测试,这样可以保证你的重构没有破坏原来的代码逻辑。