5

如何计算整个Java项目的圈复杂度?我对每种方法都有复杂性,但是如何将它们全部聚合成一个数字指标?有什么想法或现有方法吗?

我不是在寻找工具,而是在寻找算法。

简单平均几乎不起作用,因为有许多1复杂性方法,它们的复杂性并不低,但对代码库的重要性较低(在大多数情况下)。

4

4 回答 4

3

整本书都是关于代码度量的,所以你很幸运你问了一个更具体的问题。对于 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 以使其保持可维护性,因此随着项目规模的增加而增长较慢的东西是最好的。

对其进行测试、调整等。最终,代码指标很难做到恰到好处,在阅读了几篇关于开源软件的期刊论文后,我可以证明这一点,这些论文使用数字来表示“可维护性”。如果花足够的时间在上面,我们在这里能想到的任何东西都可能会得到很大的改进。

于 2012-11-26T20:04:00.330 回答
2

我找到了这个公式:

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 加权。(我不知道这是否可行,这只是一个想法)

于 2012-11-26T19:43:07.660 回答
0

我不知道这是否会有所帮助,但我只是想说出我的想法。您可以使用全局深度计数器来获取方法调用深度并在每次方法调用时更新它。您会看到这里的每个方法都手动注入了相同的代码段,但可能有一种解决方案可以将代码自动注入所有方法。我认为,通过堆栈跟踪长度的级别,您可以计算聚合的复杂性。

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
于 2012-11-26T19:49:09.553 回答
0

据我所知,您的问题还没有答案。但是 Microsoft Visual Studio 正在做的是总结给定项目的所有圈复杂度,并将结果视为汇编级别的圈复杂度。但我个人会建议你使用 Max Cyclomatic Complexity。只需简单地将最大圈复杂度视为项目圈复杂度。这样做的原因是,只要项目中存在一种具有更高循环复杂度的方法,那么项目就会成为您的软件系统的瓶颈。另一个原因是由于强连通图论,根据 McCabe 的原始论文,强连通图的圈复杂度是独立存在的电路内圈复杂度之间的最大圈复杂度。

于 2022-02-06T21:29:33.210 回答