Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cyclomatic Complexity reduction

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
    }
like image 301
cicit Avatar asked Feb 26 '16 23:02

cicit


2 Answers

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

like image 107
Rafael Teles Avatar answered Sep 21 '22 22:09

Rafael Teles


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.

like image 27
Andriy Kryvtsun Avatar answered Sep 19 '22 22:09

Andriy Kryvtsun