降低圈复杂度

Cyclomatic Complexity reduction

我有一段代码在降低圈复杂度方面遇到了问题。由于必须匹配多个条件,我不确定进一步分解它的最佳方法。使事情复杂化的是,在其中两种情况下创建了一个新对象,但在第三种情况下却没有(它调用了另一个方法)。这是伪代码:

    if (!cond3 && !cond1 && cond2 && cond4) {
        // actions to perform
        calculateValues();
        return result;
    } else if (!cond1 && cond2 && cond3) {
        // actions to perform
        Object result = new Result();
        return result;
    } else if (!cond4 && cond3 && cond1 && cond5) {
        // actions to perform
        Object result = new Result();
        return result;
    } else {
        // throw error because inputs are invalid
    }

通过提取方程的公共部分作为新变量,您可以将圈复杂度降低到 11

boolean common = !cond1 && cond2;
...
if (!cond3 && common && cond4) {
    // actions to perform
    calculateValues();
    return result;
} else if (common && cond3) {
    // actions to perform
    Object result = new Result();
    return result;
} else if (!cond4 && cond3 && cond1 && cond5) {
    // actions to perform
    Object result = new Result();
    return result;
} else {
    // throw error because inputs are invalid
}     

您应该重构该代码,使用方法来抽象那些条件,高圈表示代码需要重构。例如,假设:!cond4 && cond3 && cond1 && cond5 测试登录用户是否有车,那么您应该将该条件组合重构为一个方法:

private boolean loggedUserHasCar() {
    return !cond4 && cond3 && cond1 && cond5;
}

对其他条件做同样的事情。 if 带有 4 个条件的语句很难阅读。提取这些语句将降低您的方法圈复杂度并使您的代码更具可读性

我对您的问题很感兴趣,并尝试了较早提出的解决方案,其中提取条件以分离像这样的方法

public class Test {

public static void main(String[] args) {
    cyclometricComplexityTest();
}

static boolean cond1 = true;
static boolean cond2 = true;
static boolean cond3 = true;
static boolean cond4 = true;
static boolean cond5 = true;

public static Object cyclometricComplexityTest() {
    if (isBoolean1()) {
        // actions to perform
        Object result = null;
        calculateValues();
        return result;
    } else if (isBoolean2()) {
        // actions to perform
        Object result = new Result();
        return result;
    } else if (isBoolean3()) {
        // actions to perform
        Object result = new Result();
        return result;
    } else {
        throw new RuntimeException();
    }
}

static boolean isBoolean1() {
    return !cond3 && !cond1 && cond2 && cond4;
}

private static boolean isBoolean2() {
    return !cond1 && cond2 && cond3;
}

private static boolean isBoolean3() {
    return !cond4 && cond3 && cond1 && cond5;
}

static void calculateValues() {}

static class Result {}
}

减少循环复杂度的结果在这里(我使用MetricsReloaded IntelliJ IDEA plugin)。通过分散主要方法和辅助方法之间的复杂性,它确实有效:)

P.S。有趣的事情:我尝试将您的条件提取为局部变量,但它并没有像我最初预期的那样降低方法的复杂性。