Statische Code Analyse #1: Cyclomatic Complexity

  • Cyclomatic Complexity beschreibt anhand eines Wertes wie komplex ein Stück Quellcode ist. Komplexer Quellcode ist für den Menschlichen Verstand schwer begreifbar und lässt sich schlecht Warten bzw. Weiterentwickeln.
    Um dieses Problem zu vermeiden, setzt sich die Statische Codeanalyse dafür ein, den Quellcode sauber und einfach zu halten. In diesem Lexikoneintrag soll es einen kleinen Einblick in die Cyclomatic Complexity geben.

    Statische Codeanalyse ist für die meisten Softwareentwickler ein Thema, was sie lieber nicht hören wollen, aber dennoch nicht ganz unwichtig.

    Damit wir geschriebenen Quellcode auch noch in Zukunft einfach warten und weiter verwenden können, muss dieser in einer ordentlichen und übersichtlicher Qualität vorliegen.

    Hier kommt die statische Codeanalyse in den Vordergrund, die genau auf diese Aspekte ausgerichtet ist.

    In diesem Tutorial geht es erstmal um eine der einfachsten Aspekte dieser statischen Codeanalyse, der Cyclomatic Complexity.


    1 Was ist überhaupt diese Cyclomatic Complexity?

    Die Cyclomatic Complexity, auch McCabe-Metrik genannt, wurde 1976 durch Thomas J. McCabe eingeführt. Dahinter steckt der Gedanke, dass ab einer bestimmten Komplexität ein Modul des Quellcodes für den Menschen nicht mehr begreifbar ist. Dabei kann ein Modul eine Funktion, eine Prozedur oder allgemein ein Stück Quellcode sein.

    Die McCabe-Metrik bewertet hierbei den Sourcecode mit einer Zahl, welche die Komplexität darstellt. 1-4 ist sehr einfacherer, 5-7 ist mittlerer und 8-10 ist schwer zu verstehender Code.


    2 Berechnung der Komplexität

    Die Berechnung erfolgt durch die Anzahlt der Verzweigungen in einem Modul + 1. Die 1 kommt durch den Methodeneinstieg.

    Um die Komplexität zu berechnen brauchen wir zu aller erst ein Stück Quellcode. In Folgendem habe ich zudem mal markiert, wo der Wert erhöht wird.

    Java
    1. public final void iterateComplex(final List<String> tokens) { // complexity++
    2. if (tokens != null) { // complexity++
    3. for (final String eachToken : tokens) { // complexity++
    4. if (eachToken != null && !"".equals(eachToken.trim())) { //complexity++, complexity++
    5. System.out.println(eachToken);
    6. }
    7. }
    8. }
    9. }

    Diese kleine Code hat schon eine Komplexität von 5, lässt sich aber sehr schwer lesen. Durch die vielen verschachtelten Abhängigkeiten muss sich der Mensch vor dem Bildschirm erstmal Stück für Stück durch die verschiedenen Zustände arbeiten. Durch die Schleife wird es scheinbar unmöglich noch für einen bestimmten Eingangswert das Ergebnis schnell nachzuvollziehen.

    Daher haben wir hier den Ansatz diese Methode zu vereinfachen. Dies ist in diesem Beispiel durch sogenannte Guard Clauses möglich. Zudem wenden wir noch das Prinzip der Kapselung an. Das heißt ein großes Programm in mehrere kleinere Unterprogramme aufzuteilen.

    Sehen wir uns mal den draus resultierenden Code an:

    Hier hat die Methode callIterateSimple einen Wert von 2 bekommen und die Methode iterateSimple einen Wert von 3. Dies macht dann im Endeffekt einen Klassendurchschnitt von 2,5.


    3 Was sind nun aber die Vorteile davon?

    Ein besonders großer Vorteil ist das schreiben von einfach zu verstehendem Code. Dieser lässt sich von anderen außenstehenden Personen schnell nachvollziehen und gegebenenfalls weiterentwickeln. Zudem ist es viel einfacherer dieses Code zu Warten, wenn zum Beispiel mal ein Problem auftritt.

    Wer kennt es nicht, wenn man sich nach einer längeren Zeit mal wieder ein Stück geschriebenen Quellcode anschaut, und sich denkt: "Was hab ich denn da verbockt?".

    Diesen Fall kann man mit der Cyclomatic Complexity relativ einfach und effizient umgehen.


    4 Einbindung in IntelliJ

    Hier werde ich nur die Einbindung des Plugins für IntelliJ zeigen. Dieses Tool funktioniert aber bei allen Jetbrains Produkten gleich und kann auch gleich installiert werden.

    Das Plugin um welches es sich hier handelt ist MetricsReloaded. Dieses kann man sich über den eingebauten Marketplace downloaden oder über die verlinkte Webseite.


    Nach dem Installieren und Neustarten der IDE kann dieses auch schon benutzt werden.

    Einfach mal einen Rechtklick in eine beliebige Datei und dann wie in der Abbildung zu sehen vorgehen.


    Nun öffnet sich ein Fenster, in welchem wir unsere Code Analyse einstellen können. Hier wähle ich, dass das Plugin nur die ausgewählte Datei überprüft. Zudem wähle ich als Profil die Complexity metrics aus.


    Wir bekommen darauf eine Ausgabe mit verschiedenen Werten. Hier schauen wir uns ganz besonders die Spalte v(G) an.

    Diese beschreibt die Cyclomatic Complexity. In folgender Abbildung ist das Ergebnis des vereinfachten Codes zu finden:

    5 Quellen

    https://de.wikipedia.org/wiki/McCabe-Metrik

    https://www.softwareyoga.com/cyclomatic-complexity/

    https://plugins.jetbrains.com/plugin/93-metricsreloaded/

Teilen