Facebook
Twitter
Google+
Kommentare
12

Warum Metriken nicht immer die Wahrheit sprechen

Mal wieder eine viel zu reißerische Überschrift. Aber so ist es im knallhart recherchierten Journalismus, den wir hier nun mal betreiben, vielleicht nennt man es auch Sommerloch. Egal was es ist, heute will ich noch mal kurz über Softwaremetriken reden. Jetzt wo wir mindestens eine Metrik gemeinsam kennen, gibt es noch einen Punkt, den man erwähnen sollte.

Softwaremetriken sagen nicht immer viel aus. Nehmen wir also die Metrik von gestern. Zyklomatische Komplexität. Für mich würde ich einen Wert von Fünf als obere Grenze definieren. Ganz einfach, weil ich glaube, dass eine Methode mit 5 IF-Bedingungen vereinfacht werden sollte. Irgendwann versagt einfach das menschliche Gehirn, wenn es darum geht schnell zu verstehen, wie eine Funktion funktioniert. Ich habe es nämlich Leid, mich erst durch stundenlange Einarbeitung in die Funktion, in die Lage zu versetzen etwas anzupassen oder einen Fehler zu reparieren. Da durfte ich in einem meiner letzten Jobs oft genug durch. Jetzt würde ich also gerne folgende These aufstellen:

Jede Funktion, dessen „Komplexität“ 5 überschreitet ist zu komplex und muss umgeschrieben bzw. aufgesplittet werden.

Tja, leider funktioniert das nicht so einfach. Schauen wir uns die folgende Funktion an:

function getWeekdayName( $dayNo )
{
  switch( $dayNo ) {
    case 0: return 'Sunday';
    case 1: return 'Monday';
    case 2: return 'Tuesday';
    case 3: return 'Wednesday';
    case 4: return 'Thursday';
    case 5: return 'Friday';
    case 6: return 'Saturday';
  }
  throw Excpetion( 'DayNo not defined' );
}

Ihr ahnt es schon. Nehmen wir die Formel von gestern, so haben wir eine Komplexität von 8. Betrachtet man den Code, so ist er keinesfalls Komplex. Ich würde eine solche Funktion beim Review also intuitiv nicht als zu komplex einstufen und neu schreiben lassen.

Was haben wir also gelernt? Es ist sehr schwer Grenzen zu setzen, für Metriken, denn sie sind sehr oft sehr allgemein und damit nicht immer gleich aussagekräftig. Wir sollten die Metrik also eher als Warnhinweis sehen. Ein Wert über 5 kann also zu komplex sein und sollte deswegen noch mal untersucht werden. Ob es dann wirklich so ist, ist jedem selbst überlassen. Wir sollten auf jeden Fall festhalten, dass eine Komplexität von 8 nicht immer gleich kritisch ist.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

12 Comments

  1. @paddya: Ich finde die Variante mit dem switch-Konstrukt lesbarer und sicherer – deine Variante fängt bspw. keine negativen Werte ab. Deshalb sollte man Metriken als Warnschild sehen und folglich nicht jede Implementierung durch eine andere ersetzen, von der man nicht sichergestellt hat, dass sie äquivalent zur vorhandenen ist.

    Reply
  2. @paddya

    deine funktion versagt aber auch wenn man ihr als parameter 5.5 übergibt.. ist schliesslich ein gültiger numerischer wert aber kein gültiger array-index.
    von dem her müsstest du zumindest prüfen ob die zahl is_int() ist.
    finde aber keinesfalls das die funktion lesbar oder weniger komplex als die switch variante ist.

    lg dag

    Reply
  3. Genau das meinte ich mit meinem letzten Post, als ich sagte, dass Metriken nicht so hilfreich sind wie man immer liest.

    Wenn man beispielsweise nach jedem Commit oder bei jedem Build sich die Metriken errechnen lässt, hat man immer einen solchen Warnhinweis mit drin. Oder kann man eine Funktion irgendwie markieren (mittels phpdoc oder so), dass sie bei der Zyklischen Komplexität bitte nicht beachtet werden soll? Das wäre wiederum sehr hilfreich. Sonst hat man immer und immer wieder diesen „Warnhinweis“. Und wenn man im Code später 30 von diesen False-Positives hat, ist die Auswertung der Metrik ziemlich unübersichtlich, falsch und nicht mehr hilfreich.

    Reply
  4. Darüber kann man sich sicher streiten. Aber wenn ich eine Statistik oder Zahl haben möchte, und darin zuviele False-Positives sind, bringt mir das ganze nichts.
    Grund ist wahrscheinlich das von dir angesprochene, dass man Software nicht in Formen pressen kann und es keine strengen korrekten Grenzen gibt, ab wann Software gut oder schlecht ist. Das ist fließend, und deshalb ist das Messen so schwer und häufig nicht so aussagekräftig wie man es sich wünscht.

    Bieten denn PHP_CodeSniffer oder pDepends eine Möglichkeit, Funktionen für bestimmte Tests auszuschliessen? Und wenn nein, warum nicht? Das wäre für mich zwingend erforderlich, damit ich es mir nochmal anschaue. Als ich mir das vor Jahren angeschaut habe, konnten sie es nicht. Und das war damals das K.O.-Kriterium.

    Reply
  5. Bei den letzten Kommentaren wird deutlich wo die Problematik beim Messen eigentlich liegt. Es sind nicht einzelne Metriken oder bestimmte Anomalien in der Anwendung. Vielmehr braucht es einen zielgerichteten Messprozess um Metriken sinnvoll anwenden zu können.
    Was ist mein Informationsbedarf, den Metriken abdecken sollen?
    Welche Metriken sind dafür notwendig?
    Was sind die Zielwerte für mein Projekt, was bedeutet Qualität konkret im Anwendungsfall?
    Wie kann ich die Werte analysieren und ein Informationsprodukt erstellen?
    Beantwortet das Informationsprodukt meinen Informationsbedarf und gibt es auf dem Weg dahin Verbesserungsbedarf?

    Nun haben sich schon viele Leute Gedanken über die Anwendung von Softwaremessung gemacht. Das Konzentrat in einem Industriestandard findet sich im ISO/IEC 15939 😉

    Reply
  6. @Martin: Kann man das irgendwo kostenlos downloaden? Habe nur käufliche Versionen gefunden. Oder kannst du uns den Inhalt kurz zusammenfassen und unsere Fragen beantworten und Probleme lösen? 😉

    Reply
  7. Ich habe mich jetzt auch mal an der Sache versucht:
    http://nopaste.php-q.net/252505
    Natürlich habe ich auch direkt an ein assoziatives Array gedacht, warum paddya nicht direkt an array_key_exists gedacht hat, weiß ich nicht. Ich jedenfalls benötige diese Funktion alle naselang.

    Das Beispiel halte ich für nicht ganz so gut, weil es hier wirklich um ein simples Werte-Mapping geht. Interessanter ist vielleicht die Implementierung eines Algorithmus, diese enthalten ja oft nicht wirklich reduzierbare Logik. Beispiel:
    http://en.wikipedia.org/wiki/Tic-tac-toe#Strategy
    Hatte ich mal in JavaScript implementiert, der entsprechende Teil (nur die Strategie) enthält 10 „for“s und 22 „if“s.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen