代码的环复杂度(Cyclomatic complexity,有时也翻译成圈复杂度)是一种代码复杂度的衡量标准,在1976年由Thomas J. McCabe, Sr. 提出。java
来看看计算公式。编程
代码环复杂度 = E − N + 2编程语言
E = 程序控制流图中边的个数spa
N = 程序控制流图中点的个数翻译
很容易得出这样的结论:代码环复杂度越高,越容易出bug。code
能够想象若是须要开发人员本身去把一段代码的控制流图画出来,而后去数图中边和点的个数,这种作法效率过低了也容易出错。ci
好消息是,有一款名为Source Monitor的免费软件,可以帮咱们来度量Java代码的环复杂度。固然这款软件也支持C++和C#。开发
为了说明如何使用这款软件,我写了一段简单的Java代码。rem
package test; import java.util.ArrayList; public class monthTool { static ArrayList<String> monthCollection = new ArrayList<String>(); public static void main(String[] args) { monthTool tool = new monthTool(); tool.printV1(1); tool.printV2(2); tool.printV1(0); tool.printV2(-1); tool.printV3(3); tool.printV3(13); } public monthTool(){ monthCollection.add("Invalid"); monthCollection.add("January"); monthCollection.add("Febrary"); monthCollection.add("March"); monthCollection.add("April"); monthCollection.add("May"); monthCollection.add("June"); monthCollection.add("July"); monthCollection.add("August"); monthCollection.add("September"); monthCollection.add("October"); monthCollection.add("November"); monthCollection.add("December"); } public void printV1(int month){ System.out.println("Month is: " + getMonthNameV1(month)); } public void printV2(int month){ if( month >= 1 && month <= 12) System.out.println("Month is: " + getMonthNameV2(month)); else System.out.println("Please specify a valid month"); } public void printV3(int month) { System.out.println("Month is: " + getMonthNameV3(month)); } public String getMonthNameV2(int month){ if( month == 1) return "January"; else if( month == 2) return "Febrary"; else if( month == 3) return "March"; else if( month == 4) return "April"; else if( month == 5) return "May"; else if( month == 6) return "June"; else if( month == 7) return "July"; else if( month == 8) return "August"; else if( month == 9) return "September"; else if( month == 10) return "October"; else if( month == 11) return "November"; else if( month == 12) return "December"; else return "Invalid"; } public String getMonthNameV1(int month){ switch (month){ case 1: return "January"; case 2: return "Febrary"; case 3: return "March"; case 4: return "April"; case 5: return "May"; case 6: return "June"; case 7: return "July"; case 8: return "August"; case 9: return "September"; case 10: return "October"; case 11: return "November"; case 12: return "December"; default: return "Invalid"; } } public String getMonthNameV3(int month){ try { return monthCollection.get(month); } catch (java.lang.IndexOutOfBoundsException e){ return "Invalid"; } } }
其中我用了三种不一样的方式实现了同一个逻辑,将一个表明月份的整数转成了月份名称。get
下面是Source Monitor的具体用法。
1. 建立一个新的项目:
这里能看到全部Source Monitor支持的编程语言。
2. 指定您本地的Java项目文件地址:
3. 指定您的Java项目文件夹内,您但愿SourceMonitor计算哪些Java文件的环复杂度。
4. 点OK,就能够开始扫描啦。
很快Source Monitor就将咱们指定的Java文件的环复杂度计算完毕。点击菜单“Display Method Metrics”来查看结果:
从环复杂度扫描结果能看出,明显第三种从月份名称集合里经过ArrayList自带的get方法取得月份名称是最优的解法——环复杂度仅为2。
也能够经过图表的方式更直观得看到方法的环复杂度比较:
X轴的值表明每一个方法的环复杂度,Y轴表明这些环复杂度的不一样值出现的次数。
好比下图的意思是,环复杂度为1的方法(X轴刻度为1的节点)共有4个(Y轴刻度为4),环复杂度为2的方法(X轴刻度为2的节点)有1个(Y轴刻度为1)。以此类推。
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码: