am 7. September 2009
Ich hatte es ja letzte Woche angekündigt, dass wir in den nächsten Wochen ab und zu mal eine Softwaremetrik besprechen wollen. Und heute soll es schon damit losgehen. Als erstes kommt natürlich die am häufigsten angewendete Metrik dran. Zyklomatische Komplexität (ZK) oder auch Cyclomatic Complexity oder auch McCabe Metrik. Wir nennen es aber Zyklomatische Komplexität, da ich ich ein Freund der deutschen Sprache bin (auch wenn ich sie nicht immer beherrsche).
Erinnern wir uns noch mal kurz an die Definition. Eine Softwaremetrik bildet eine Eigenschaft von Software in einen Zahlenwert ab. Bei der ZK geht es darum herauszufinden, wie komplex und damit auch wie wartbar eine Funktion ist. Wir gehen also davon aus, dass eine Funktion, je komplexer sie wird, desto eher Probleme bereiten wird. Was ich mit meiner Erfahrung auch bestätigen kann und ihr sicherlich auch.
Das Problem ist jetzt natürlich herauszufinden, wie Komplexität zu definieren ist. Für McCabe, den Erfinder dieser Metrik, war es die Anzahl der linear unabhängigen Pfaden durch die Funktion. Also wie viele Wege gibt es durch eine Methode. Nehmen wir ein einfaches Beispiel:
function not( $boolVal )
{
if ( $boolVal == true ) {
$result = false;
} else {
$result = true;
}
return $result;
}
Kann ich eine Funktion überhaupt not nennen? Egal. Mir zumindest. Schauen wir uns die Methode an, dann fallen uns zwei Wege durch diese auf. Einmal den true Fall und einmal den false Fall. Damit wäre der ZC Wert für diese Funktion 2. Aber wie berechnet man das automatisiert für jede x-beliebige Funktion.
Der formelle Ansatz, der aus der Graphentheorie stammt, ist nicht so wirklich einfach. Jede Methode kann durch einen Kontrollflußgraphen (Beispiel) dargestellt werden (gehen wir mal wann anders drauf ein, versprochen). Die Zyklomatische Komplexitätszahl (ZKZ) wird dann durch folgende Funktion dargestellt:
ZKZ=e−n+2
Wobei e die Anzahl der Kanten ist und n die Anzahl der Knoten. Nach Andre’s wunderbarer Einführung in die Graphentheorie sollte das für euch ja ziemlich einfach sein. Um das automatisiert zu berechnen könnte man jetzt komplexe Algorithmen aufstellen. Muss man aber gar nicht. Denn wie der Zufall es will, gibt es eine viel einfache Funktion, die diesen Wert berechnet. Wir müssen nämlich nur alle bedingte Anweisungen aufeinander addieren, eins drauf addieren und schon haben wir den gleichen Wert. In PHP wäre es also die Anzahl aller IF, CASE, DEFAULT, CATCH, FOR, FOREACH, WHILE, DO und ELSEIF. Das zu berechnen sollte uns doch gelingen. Zählen wir schnell unser Beispiel durch. Eins + Eins = Zwei. Juhu, alles bewiesen. Wir haben jetzt also eine einfache Formel zum Berechnen der Zyklomatischen Komplexität.
Natürlich müssen wir das nicht mehr selbst berechnen. Der PHP_CodeSniffer hat bereits einen solchen Sniff integriert und auch pDepends von Manuel Pichler kann diese Zahl berechnen. Einen Wert, den man immer wieder hört, den die Komplexität nicht überschreiten soll ist 10. Meiner Meinung ist der Wert schon viel zu hoch, aber die Allgemeinheit scheint da anders zu denken. Eine Methode mit 5 FOR-Schleifen und 5 IF-Bedingungen schreit doch förmlich umgeschrieben zu werden. Den Wert kann man aber für sich selbst definieren.
So das war der erste Teil meiner Metriken Reihe. Ist doch länger geworden als gedacht, deswegen schicke ich morgen nochmal kurz was nach. Als nächstes kommt die n-Path Complexity, die ich nächste Woche angehen will. Bis dahin muss ich mir aber nochmal ein paar Dinge durchlesen. Was mich aber noch interessieren würde, wäre der Wert, den ihr als Limit setzen würdet. Ab welchem Wert würdet ihr euch eine Funktion noch einmal anschauen?