Bei den bereits zitierten Gedanken zu Programmiertechniken beschäftigte mich auch eine besonders folgenschwere Form von schlechter Programmstruktur, nämlich die Viel-Zu-Lange-Funktionen-Seuche.
In vielen Projekten gibt es Aufgabenstellungen, deren Lösung eine größere Anzahl Berechnungsschritte erfordert. Aus irgendwelchen Gründen ergibt es sich mancherorts, dass man diese größere Anzahl Berechnungsschritte kurzerhand sequentiell (einen nach dem anderen) in eine einzige Funktion mit einem Namen ähnlich BerechneJetztAlles() hineinschreibt.
Wo liegt das Problem? Diese Frage hört man vom ursprünglichen Autor, wenn man als neu Hinzukommender den Programmcode drei Tage lang angesehen hat und nun mit Augen voller Fragezeichen auf ihn zukommt. Da liegt das Problem: Kein Mensch kann solche Funktionen mehr verstehen, die bis zu 1000 Zeilen lang sind und in sich eigentlich mindestens 5 separate Aufgaben der Reihe nach erledigen. Funktionen sind dafür erfunden worden, dass man exakt spezifiziert, was reinkommt und was rauskommt. Im Gegenzug kann man sich dies leicht merken und – vor allem – auf einen Blick wieder anlesen. Innerhalb einer ellenlangen Funktion dagegen weiß man praktisch gar nichts mehr.
Man wundert sich ja geradezu, wie der ursprüngliche Autor in der Lage war, zu verstehen und zu kontrollieren, was in der viel zu langen Funktion denn vorging. Und hier kommt der Debugger ins Spiel.
Ein Debugger (von englisch bug, Fehler) ermöglicht das Zuschauen beim Ablauf eines Programms, auch genannt Ablaufverfolgung. Der Debugger führt das Programm schrittweise aus und kann bei jeder Programmzeile anhalten. Im Bild oben rechts ist diese Zeile durch das nette grüne Dreieck gekennzeichnet. Der Programmierer kann sich dann den Inhalt der Variablen in jenem Programmschritt anzeigen lassen, ähnlich der Variablenliste im klickbaren Bild unten links.
Eigentlich eine schöne Sache. Aber leider scheinen einige Debugger-Benutzer vergessen zu haben, dass ein Debugger ein Werkzeug zur Fehlersuche ist und nicht zum Verstehen eines Programmes. Wenn meine Frage zur Funktionsweise einer Funktion damit beantwortet wird, “geh mal mit dem Debugger schrittweise durch, dann siehst du, was passiert,” dann ist der Programmcode – wie mein deutlicher Kollege B. sagen würde – dann ist das totaler Mist.
Wenn man eine Funktion nicht durch Lesen verstehen kann, dann muss die Funktion eben aufgeteilt werden in kleinere Funktionen, die man verstehen kann. Dazu sind Funktionen da. Wenn die verwendete Datenstruktur dazu schlecht benutzbar ist, muss man sich eben neue passendere Datenstrukturen überlegen. Dazu sind Datenstrukturen da.
Wer sich dagegen durch den Debugger vorgaukeln lässt, dass eine ellenlange Funktion verstehbar sei, weil man “ja im Debugger durchsteppen” könne, ist bereits untrüglich der Viel-Zu-Lange-Funktionen-Seuche zum Opfer gefallen. Da hilft nur, den Debugger mal für 3 Monate im Schrank zu lassen und den Programmcode wieder durch den Programmcode verstehbar zu machen. Und meine negative Meinung über IDEs wird auch nicht besser durch die Tatsache, dass die IDEs das Anwerfen des Debuggers für den Programmierer möglichst einfach machen wollen.
Nochmal: Ein Debugger verführt durch die Ablaufverfolgung zu viel zu langen Funktionen.
Deshalb: Debugger are evil. Debugger sind ein Übel.
Debugger sind böse.