如何计算整个Java项目的cyclomatic complexity?我对每种方法都有复杂性,但是如何将它们汇总为一个数字度量标准?任何想法或现有方法?如何计算项目的圈复杂度(不是类/函数)?
我不是在寻找一种工具,而是一种算法。
简单平均难以奏效,因为有许多复杂性方法,复杂度并不低,但对代码库(在大多数情况下)并不重要。
如何计算整个Java项目的cyclomatic complexity?我对每种方法都有复杂性,但是如何将它们汇总为一个数字度量标准?任何想法或现有方法?如何计算项目的圈复杂度(不是类/函数)?
我不是在寻找一种工具,而是一种算法。
简单平均难以奏效,因为有许多复杂性方法,复杂度并不低,但对代码库(在大多数情况下)并不重要。
我发现公式:
TCC = Sum(CC) - Count(CC) + 1
TCC: Total CC
Sum(CC): Sum of CC of all functions
Count(CC): Number of functions
来源:http://www.aivosto.com/project/help/pm-complexity.html
但也许是太有限了。
另一个想法是将程序的调用图看作程序本身,并计算调用图的CC。节点将由他们的CC加权。 (我不知道这是否可行,它只是一个想法)
我不知道这是否会有所帮助,但我只是想告诉我的想法。您可以使用全局深度计数器获取方法调用深度并在每次方法调用时更新它。 您可以手动在这里的每个方法中看到相同的代码片段,但可能会有一个将代码自动注入到所有方法的解决方案。利用堆栈跟踪长度的级别,我认为可以计算总体复杂度。
public class Cyclomatic
{
public static int max = Integer.MIN_VALUE;
static void a()
{
b();
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
static void b()
{
c();
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
static void c()
{
int temp = Thread.currentThread().getStackTrace().length;
if (temp > max)
max = temp;
}
public static void main(String[] args)
{
a();
System.out.println(max);
}
}
输出:
5
整本书都是写在代码度量,那么你是幸运的,你问一个更具体的问题。对于Java圈复杂度,可以找到超过5或6的圈复杂度的方法的数量(在此选择数字)。如果这个数字超过了你方法数量的一定百分比,那么整体圈复杂度就很差。对于百分比来说,一个好的数字完全取决于项目的规模,所以也许不是只用方法的数量来划分,而是可以减少分部中的方法数量,方法是让数量较大的方法缓慢增长,例如随着项目的发展,尝试使其更稳定的平方根或对数。
也许是这样的:
public double evaluateCyclomaticComplexity(List<MethodStat> methodStats) {
int bad = 0;
for (MethodStat methodStat : methodStats)
if (methodStat.getCyclomaticComplexity() >= 6)
bad++;
double denominator = Math.sqrt(methodStats.size());
return bad * 100.0/denominator;
}
这里返回的数字越小越好。对于真的不好的项目,这将返回大于100的东西。
分母函数应该表示随着代码库的增长,复杂性增长的快慢。通常情况下,随着代码增长,您希望每个函数的CC值更低,以便它能够保持可维护性,所以随着项目大小的增加,增长速度会越慢越好。
对它进行测试,调整等等。最终,代码度量标准很难得到恰到好处,我可以在阅读关于使用数字来表示“可维护性”的开源软件的几篇期刊论文后证明。如果在这里花费了足够的时间,那么我们在这里可以提出的任何事情都可能会大大改善。