5

I have a block of code that I am having an issue reducing the cyclomatic complexity of. Because of the multiple conditions that have to match, I am not sure the best way to break it down further. Complicating matters is that in 2 of the cases a new object is created, but not in the third (it calls out to another method). This is the pseudocode:

    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
    }
Cœur
  • 37,241
  • 25
  • 195
  • 267
cicit
  • 581
  • 5
  • 24
  • Problem is Sonar says CC of 12 and our threshold is 10. I feel like it is fine as well, but we have to live by that threshold. – cicit Feb 26 '16 at 23:58

3 Answers3

6

You should refactor that code, using methods to abstract those conditions, high cyclomatic indicates that the codes need refactoring. For example, lets say that: !cond4 && cond3 && cond1 && cond5 tests if the logged user has a car, then you should refactor that combination of conditions to a method:

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

Do the same thing to the other conditions. if statements with 4 conditions are hard to read. Extracting those statements will reduce your method cyclomatic complexity and make your code more readable

Rafael Teles
  • 2,708
  • 2
  • 16
  • 32
2

I'm really interested in your problem and tried proposed earlier solution with extracting conditions to separate methods like this

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 {}
}

The results of reducing of Cyclometric Complexity are here (I used MetricsReloaded IntelliJ IDEA plugin). It really works by spreading the complexity between main and auxiliary methods :)

enter image description here

P.S. interesting thing: I tried to extract your conditions as local variables and it didn't reduce method complexity as I initially expected.

Andriy Kryvtsun
  • 3,220
  • 3
  • 27
  • 41
1

You can decrease cyclometric complexity to 11 with extraction common part of your equations as new variable

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
}     
Andriy Kryvtsun
  • 3,220
  • 3
  • 27
  • 41