测量数据映射函数的循环复杂度&关闭

时间:2012-08-23 12:48:36

标签: unit-testing complexity-theory cyclomatic-complexity

根据圈复杂度的基本规则,下面的代码应该具有2的复杂度(只有一个分支点 - for循环)。

function SumArray(array_to_sum) {
    var sum = 0;
    for (var i = 0; i < array_to_sum.length; i++) {
        sum += array_to_sum[i];
    }
    return sum;
}

许多现代框架等提供数据映射功能,例如jQuery.each()Underscore.js框架中的大多数方法。请考虑以下代码:

function SumArray(array_to_sum) {
    var sum = 0;
    jQuery.each(array_to_sum, function(index, value) {
        sum += value;
    });
    return sum;
}

根据典型的圈复杂度规则,第二个例子的CC测量值为1.工作完全相同,函数的人类复杂性根本没有改变。我所做的只是交换一种循环数据的方法,用于循环数据的不同方法。

同样考虑这个设计的例子,我们将原始函数的内部包装在一个自调整闭包中,为外部方法产生1的圈复杂度,而实际上并没有改变该方法的工作方式:

function SumArray(array_to_sum) {
    return (function() {
        var sum = 0;
        for (var i = 0; i < array_to_sum.length; i++) {
            sum += array_to_sum[i];
        }
        return sum;
    })();
}

圈复杂度的真实度量是否应考虑数据映射/缩减方法,例如jQuery.each(),尤其是在使用匿名本地闭包时?

也许闭包应该将它们的复杂性导出到结束父级。也许方法通常应该能够定义一个导出复杂性,该复杂性被添加到调用它的任何函数的复杂性中 - 例如,jQuery.each()可能具有1的导出复杂度,因此使用它来代替正常循环计算复杂度相同。

2 个答案:

答案 0 :(得分:1)

Cyclomatic Complexity是衡量代码可读性的标准。 McCabe描述了部分测量Cyclomatic Complexity的前提“此外,复杂的组件也难以理解,难以测试,难以修改。”

即。对于读者来说很复杂的代码更容易出错,因为它更难测试(通过单个代码块的路径更多。它可能会保持错误,因为它很难修改,因为它们更难理解,所以人们避免修改它

答案 1 :(得分:-2)

圈复杂度的真实度量是否应包括数据映射/缩减方法(如jQuery.each())的注意事项,尤其是在使用匿名本地闭包时?

是。当然。不管。

但请记住,“圈复杂度”是the work of man;它只是我们为特定的启发式家族提供的名称,用于估计特定代码的“复杂”程度。如果您正在为jQuery(或任何其他携带lambda的语言)设计一个圈复杂度审计工具,那么,jQuery.each()的特殊情况将是一个很好的功能,并让用户定义“出口复杂性“他们自己的功能将是一个更好的功能。但是,让我们不要忘记这是如何计算圈复杂度的最真实方式的宏伟语言。这只是一种启发式的改进。我可以从头脑中再给你十种可能的改进。