Warum Code, der nicht ausgeführt wird, immer mehr Arbeit bedeutet

Seek and Destroy: Toten Code aufspüren und löschen!

Jan Weddehage

© Shutterstock / Captblack76

Der beste Code ist der, um den man sich nicht kümmern muss. Und man muss sich um Code nicht kümmern, wenn er gar nicht existiert. Zeilen zu löschen, die nicht ausgeführt werden, ist nur eine Option unter anderen, sondern ein notwendiges Muss. Aber wie kommt man totem Code auf die Schliche?

Toter Code ist tot. Was auf dem ersten Blick logisch erscheint, findet in der Programmierwelt oftmals nicht ausreichend Gehör. Nur ungern trennen sich viele von den von ihnen geschriebenen Zeilen. Es gibt noch weitere Gründe, warum Coderelikte entstehen und oftmals nicht auffallen. So fehlt es oftmals schlicht am nötigen Know-how, um die Lebensdauer einzelner Elemente richtig einzuschätzen.

Manchmal wird auch davon ausgegangen, dass alte Versatzstücke zwar in der aktuellen Version keine Berücksichtigung finden, später aber wieder eingesetzt werden können. Statt die alten Schnipsel aufzubewahren, sollte in solchen Fällen lieber auf die Versionskontrolle zurückgegriffen werden. Zu bedenken ist allerdings, dass nur selten auf Code Bezug genommen wird, der einmal gelöscht worden ist. Verantwortlich hierfür sind die kontinuierlich sich verändernden Techniken und Frameworks.

Faulheit der Grund für toten Code?

Dan Crosta geht in seinem Artikel einen Schritt weiter. Er behauptet, es ist im Wesentlichen der Faulheit von Programmieren geschuldet, dass toter Code nicht konsequent gelöscht wird. Etwas nicht zu tun, ist meistens einfacher, als etwas zu tun – ein Trugschluss. Im Laufe der Zeit überwiegen die Nachteile dieser Praxis die positiven Effekte doch deutlich.

Allerdings ist es für Crosta kein Nachteil, faul zu sein – im Gegenteil. Richtig umgesetzt kann Faulheit das Programmiererleben extrem vereinfachen. Hierzu gehört, Probleme dann zu beheben, wenn sie noch einfach zu lösen sind und nicht erst, wenn sie zu großen und komplexen Ungetümen angewachsen sind. Toter Code sollte also nicht auf die lange Bank geschoben werden.

Was ist toter Code überhaupt?

Unter totem Code versteht man Zeilen und Funktionen, die nicht mehr ausgeführt werden. Solche Bausteine behindern in der Regel die Wartbarkeit der Codebasis. Je komplexer ein Quelltext, desto schwieriger wird es, Verbesserungen vorzunehmen oder neue Features – und seien sie noch so klein – zu implementieren.

Die Umgehenslösungen, die ein immer komplexerer Code erfordert, machen vielen Entwicklern das Leben unnötig schwer. Bei jeder Veränderung muss berücksichtig werden, wie die Neuerungen mit den existierenden Features interagieren und wie sie auf bekannte und Macken und Bugs reagieren. Der große Nachteil von toten Codeversatzstücken besteht dabei darin, dass die von ihnen verursachten Interaktionen und Fehler in Betracht gezogen werden müssen, obwohl die betroffenen Zeilen überhaupt nicht mehr ausgeführt werden.

Das Entfernen von toten Codezeilen reduziert nicht nur die Fehleranfälligkeit, sondern versetzt die Entwickler ebenfalls in die komfortable Lage, sich weniger mit Kompatibilitätsfragen und Kompilierungsproblemen rumschlagen zu müssen. Schlanker Code ist einfacher zu verwalten und zu bearbeiten.

Toten Code aufspüren und entfernen: So geht’s

Das toter Code ein effizientes Arbeiten behindert und die Entfernung nicht nur einem Selbst, sondern dem gesamten Team Vorteile bringt, liegt also auf der Hand. Allerdings bleibt nach wie vor die Frage bestehen, wie solcher Quelltext überhaupt aufgespürt werden kann.

Wie Crosta argumentiert, kann in einfachen Fällen bereits ein geschärftes Situationsbewusstsein beim Programmieren dabei helfen, toten Code zu identifizieren und zu entfernen. Während des Schreibens neuer Zeilen sollte kontinuierlich darauf geachtet werden, ob bestimmte Befehle nicht mehr ausgeführt werden können. Ist dies der Fall, sollten die betreffenden Zeilen direkt gelöscht werden.

Abgerundet werden kann diese Strategie dadurch, dass nach der Implementierung der neuen Funktionen der umliegende Code auf mögliche Kompatibilitätsprobleme hin untersucht wird. Bevor die überarbeiteten Codezeilen also zur Überprüfung (Stichwort: Code Review) an die Mitarbeiter geschickt werden, sollte zunächst selbst getestet werden, ob die neuen Features die umliegende Codebasis in irgendeiner Weise einschränken und so neuen, toten Code produzieren. Das erleichtert die Praxis des Code Reviews, da nur die neuen Eigenschaften von den Kollegen gegengecheckt werden müssen.

Run-Time-Tools schaffen Abhilfe in schwierigen Fällen

In schwierigeren Fällen – wenn beispielsweise unwissentlich die letzte Verwendung einer Klasse oder Funktion geändert wird – rät Crosta, auf Run-Time-Tools zurückzugreifen, da ein geschärftes Situationsbewusstsein oftmals nicht mehr ausreicht. Solche Werkzeuge werden normalerweise während des Testings eingesetzt, um zu überprüfen, ob in den Testszenarien der Code angemessen ausgeführt wird.

Wie er am Beispiel des Python-Tools coverage.py demonstriert, können Run-Time-Tools auch derart eingesetzt werden, dass sie im normalen Ablauf checken, welche Bausteine benutzt werden und welche nicht. Um toten Code im eigenen Projekt zu ermitteln, ist es nicht nötig, die Standardbibliotheken oder installierten Packages zu durchsuchen. Notwendig ist nur eine Branch-Coverage, die überprüft, ob die true und false Bedingungen jedes if-Statements ausgeführt werden. Nachdem das Programm durchgelaufen ist, geben die im anschließenden Report rot unterlegten Zeilen Auskunft darüber, welche Codebausteine nicht ausgeführt worden sind. Diese Elemente sind laut Crosta potenzielle Kandidaten für toten Code.

Fazit

Das Code-Coverage ist allerdings keine eierlegende Wollmilchsau. Ein einziger Coverage-Run ist nicht ausreichend, um zu bestimmen, ob eine Zeile oder Feature generell nicht funktioniert. Erst die Überprüfung der Codebasis liefert eindeutige Ergebnisse. Hinzu kommt, dass das Code-Coverage in Performancefragen nicht gut wegkommt. Ebenso bekommen die aus dieser Methode hervorgehenden Reports nicht immer alle möglichen Kandidaten in den Blick. Und letztlich macht es ebenfalls einen großen Unterschied, ob Applikationen oder Libraries und Frameworks entwickelt werden. Aber trotz alledem kann mit gutem Gewissen behauptet werden: Toter Code sollte gelöscht werden – auch wenn die Umsetzung ein wenig kniffelig ist.

Aufmacherbild: Death with scythe via Shutterstock / Urheberrecht: Captblack76

Geschrieben von
Jan Weddehage
Jan Weddehage
Jan Weddehage studiert an der Goethe Universität Frankfurt am Main und arbeitet seit März 2015 als Werkstudent bei Software & Support. Kontakt: jan[at]janweddehage.de
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: