早期报表和圈复杂度

Sto*_*ica 5 cyclomatic-complexity sonarqube

我喜欢这种早期回报的写作风格:

public static Type classify(int a, int b, int c) {
    if (!isTriangle(a, b, c)) {
        return Type.INVALID;
    }
    if (a == b && b == c) {
        return Type.EQUILATERAL;
    }
    if (b == c || a == b || c == a) {
        return Type.ISOSCELES;
    }
    return Type.SCALENE;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,每个return语句都会增加Sonar计算的圈复杂度指标.考虑这个选择:

public static Type classify(int a, int b, int c) {
    final Type result;
    if (!isTriangle(a, b, c)) {
        result = Type.INVALID;
    } else if (a == b && b == c) {
        result = Type.EQUILATERAL;
    } else if (b == c || a == b || c == a) {
        result = Type.ISOSCELES;
    } else {
        result = Type.SCALENE;
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

Sonar报告的后一种方法的圈复杂度低于第一种,为3.我被告知这可能是CC指标错误实施的结果.或者声纳是否正确,这真的更好吗?这些相关问题似乎不同意:

https://softwareengineering.stackexchange.com/questions/118703/where-did-the-notion-of-one-return-only-come-from

https://softwareengineering.stackexchange.com/questions/18454/should-i-return-from-a-function-early-or-use-an-if-statement

如果我添加对更多三角形类型的支持,则这些return语句将相加,从而在度量标准中产生显着差异并导致Sonar违规.我不想坚持使用// NOSONAR该方法,因为这可能会掩盖将来添加到该方法的新功能/错误的其他问题.所以我使用第二个版本,即使我不喜欢它.有没有更好的方法来处理这种情况?

maa*_*nus 2

不是真正的答案,但评论太长了。

这个SONAR规则似乎被彻底打破了。你可以重写

b == c || a == b || c == a
Run Code Online (Sandbox Code Playgroud)

作为

b == c | a == b | c == a
Run Code Online (Sandbox Code Playgroud)

并在这个奇怪的游戏中获得两分(甚至可能获得一些速度,因为分支的成本很高;但这无论如何都是由 JITc 决定的)。

规则声称,圈复杂度与测试数量有关。新没有,这是一件好事,因为显然两个片段的有意义测试的数量是完全相同的。

有更好的方法来处理这种情况吗?

实际上,我确实有一个答案:对于每次提前返回,|而不是||一次。:D

现在严肃地说:有一个请求注释的错误,允许禁用单个规则,该规则被标记为已修复。我没有再看下去。