写点什么

使用工具 Source Monitor 测量您 Java 代码的环复杂度

作者:Jerry Wang
  • 2021 年 12 月 02 日
  • 本文字数:1843 字

    阅读完需:约 6 分钟

使用工具Source Monitor测量您Java代码的环复杂度

代码的环复杂度(Cyclomatic complexity,有时也翻译成圈复杂度)是一种代码复杂度的衡量标准,在 1976 年由 Thomas J. McCabe, Sr. 提出。


来看看计算公式。


代码环复杂度 = E − N + 2


E = 程序控制流图中边的个数


N = 程序控制流图中点的个数


很容易得出这样的结论:代码环复杂度越高,越容易出 bug。



可以想象如果需要开发人员自己去把一段代码的控制流图画出来,然后去数图中边和点的个数,这种做法效率太低了也容易出错。


好消息是,有一款名为 Source Monitor 的免费软件,能够帮我们来度量 Java 代码的环复杂度。当然这款软件也支持 C++和 C#。



为了说明如何使用这款软件,我写了一段简单的 Java 代码。


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";
}
}
}
复制代码


其中我用了三种不同的方式实现了同一个逻辑,将一个代表月份的整数转成了月份名称。


下面是 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 的原创技术文章,请关注公众号"汪子熙"。


发布于: 5 小时前阅读数: 9
用户头像

Jerry Wang

关注

个人微信公众号:汪子熙 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。

评论

发布
暂无评论
使用工具Source Monitor测量您Java代码的环复杂度