2016-02-26 23 views
5

Mam blok kodu, że mam problem zmniejszający złożoność cykliczności. Ze względu na wiele warunków, które muszą się zgadzać, nie jestem pewien, jak najlepiej to przełamać. Sprawą komplikującą jest to, że w 2 przypadkach tworzony jest nowy obiekt, ale nie w trzecim (wywołuje on inną metodę). To jest pseudokod:Zmniejszenie złożoności cykllomatycznej

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 
    } 
+2

Wygląda dobrze dla mnie. –

+0

@LouisWasserman, to ten sarkazm? – jaco0646

+2

@ jaco0646, nie, nie jest. –

Odpowiedz

6

Należy byłaby ten kod, za pomocą metody abstrakcyjne te warunki, wysoko cyclomatic wskazuje, że kody wymagają refaktoryzacji. Na przykład, powiedzmy, że: !cond4 && cond3 && cond1 && cond5 testy czy zalogowany użytkownik ma samochód, to należy byłaby to połączenie warunkach sposobu:

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

Czy to samo do innych warunków. if Wyrażenia z 4 warunkami są prawdopodobnie bardzo trudne do odczytania. Wyodrębnianie tych oświadczeń będzie zmniejszyć złożoność cyclomatic metoda i uczynić kod bardziej czytelnym

1

Można zmniejszyć cyklometryczne złożoności do 11 z ekstrakcji wspólnej części swoich równań jako nową zmienną

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

Jestem bardzo zainteresowany problemem i wypróbowane rozwiązanie zaproponowane wcześniej z wydobycia warunki do odrębnych metod jak tego

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

wynikami zmniejszenie złożoności cyklometrycznej są tutaj (użyłem MetricsReloaded IntelliJ IDEA plugin). To naprawdę działa poprzez rozłożenie złożoność między głównych i pomocniczych metod :)

enter image description here

PS: Ciekawa rzecz: próbowałem wyodrębnić twoje warunki jako zmienne lokalne i nie zmniejszyło to złożoności metody, jak się początkowo spodziewałem.