如何计算项目的圈复杂度(不是类/函数)?

时间:2012-11-26 19:23:04

标签: java cyclomatic-complexity

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

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

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

3 个答案:

答案 0 :(得分: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的功能越来越低,以便它可以保持可维护状态,因此随着项目大小的增加,增长速度会变慢。

测试它,调整它等等。最终,代码指标很难得到正确的,我可以在阅读几篇关于使用数字代表&#34;可维护性的开源软件的期刊论文后证明这一点。如果花费足够的时间,我们在这里可以提出的任何事情都可能会大大改善。

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

答案 2 :(得分: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