Die IT-Branche wird oft als schnelllebig empfunden. Wer die Diskussionen um derzeit angesagte Web-Frontend-Technologien mitverfolgt, kann ein Lied davon singen. Auf der anderen Seite aber gibt es Bücher, die auch nach über 15 Jahren kaum was von ihrer Aktualität eingebüßt haben. „Working Effectively with Legacy Code“ von Michael Feathers ist ein solches Buch (deutsche Auflage: “Effektives Arbeiten mit Legacy Code”) . Es setzt sich mit den Problemen auseinander, auf die wir so treffen, wenn wir in der Softwareentwicklung schwer wartbaren Code anpassen müssen.

In diesem Blogbeitrag wollen wir einen Blick auf das Buch werfen und beleuchten, warum es guten Gewissens als Standardwerk im Umgang mit Code-Altlasten gesehen werden kann.

Feathers definiert in seinem Buch Legacy-Code schlicht und schnörkellos als Code ohne Tests. Warum? Ganz einfach: Nur wenn Code mit Tests versehen ist, lassen sich Änderungen zuverlässig vornehmen. Die Tests dienen dabei als Sicherheitsnetz, die uns anzeigen, ob wir durch Umbauarbeiten das Verhalten der Software (gewollt oder ungewollt) geändert haben.

Problemorientierte Kapitel

Soweit, so gut. Was das Buch so wertvoll macht, sind m.E. drei wichtige Punkte:

  • Problemorientierte Kapitel
  • Ein Katalog mit konkreten Refactoring-Techniken
  • Anschauliche, zeitlose Beispiele

Das Buch zu einem Großteil in Kapitel gegliedert, die problemorientiert den Leser ansprechen, und das geht schon bei den Überschriften los: „I Can’t Get This Class into a Test Harness“, „I Need to Make A Change. What Methods Should I Test?“, „I’m Changing the Same Code All Over the Place“. Wenn man sich mit seinem Refactoring-Problem direkt schon in der Überschrift wiederfindet, kann man direkt einsteigen und findet im Kapitel konkrete Vorgehensweisen. Für die Veranschaulichung werden überwiegend objektorientierte Sprachen und Techniken (z.B. Java, C++) verwendet. Nun sind zwar aktuell auch andere Paradigmen wie funktionales Programmieren in aller Munde, aber für die Strukturierung komplexer Codebestände sind OO-Techniken nach wie vor das Mittel der Wahl (change my mind!) und auch unabhängig davon sind viele Ansätze des Buches anwendbar.

Martin Fowlers Refactoring-Techniken reloaded: Der Katalog

Im Anschluss an diese Kapitel folgt noch ein weiterer Teil, in dem eine Vielzahl an Techniken vorgestellt wird, um Code-Abhängigkeiten aufzulösen, damit Klassen mit Tests versehen werden können. Diese Techniken, wenn sorgfältig angewendet, lassen das Code-Verhalten unverändert, so wie es von Code-Refactorings erwartet wird. Teilweise mögen sie noch nicht zu besserem Code-Design führen, aber mit Hilfe von anschließend ergänzter Tests lässt sich dann auch der Code zu einem besseren Design umbauen.

Diese Techniken werden mit Beispielen und einer konkreten Abfolge von Schritten eingeführt, die nötig sind, um die Technik anzuwenden. Und in den übrigen Kapiteln finden sich immer wieder Verweise zu konkreten Techniken, die sich für bestimmte Probleme anbieten.

Ansätze, die auch heute noch aktuell sind

Beim Lesen des Buchs bekommt man eine Vielzahl von Ansätzen an die Hand, die einem im Umgang mit Legacy-Code helfen. Es gibt natürlich ein paar Stellen, an denen sich der Stand der Technik weiterentwickelt hat (der Umgang mit der JUnit-Bibliothek oder manche Sprachkonstrukte wurden natürlich modernisiert), aber für die grundsätzlichen Themen, die das Buch bearbeitet, ist das fast immer nebensächlich.

Und dann gibt es immer mal wieder ein paar Techniken, die sich auch einsetzen lassen, wenn man nicht direkt in Refactoring-Themen aktiv ist. In „Telling the Story of the System“ beschreibt Feathers, wie in einem Gespräch die Grobübersicht eines großen Systems ermittelt werden kann.

Wenn man in wenigen Sätzen versucht, die System-Architektur jemand anderem zu vermitteln, wird man zu Vereinfachungen greifen müssen, um gewisse Ausnahmen auszuklammern. Diese Vereinfachungen, die sich im Gespräch ergeben, können aber z.B. Hinweise auf mögliche Architekturverbesserungen sein. Ein weiterer Aspekt bei einer solchen Kurzbeschreibung ergibt sich aber auch bei möglichen Erweiterungen: Wenn sich beispielsweise für eine fachliche Erweiterung zwei technische Lösungen anbieten, kann es sein, dass sich je nach Umsetzung die Kurzbeschreibung etwas ändern würde bzw. eine weitere Vereinfachung formuliert werden muss, damit die Beschreibung noch zur Architektur passt. Dies kann ein Hinweis darauf sein, dass eine technische Lösung gegenüber einer anderen im Nachteil ist. Im Buch wird dies am Beispiel einer Erweiterung der JUnit-Bibliothek veranschaulicht.

Michael Feathers hat die Techniken im Buch in vielen Refactoring-Workshops erarbeitet. Richtig wertvoll sind sie auch gerade deshalb, weil sie sich dafür eignen, dass Teams mit Altanwendungen es wieder schaffen, regelmäßig qualitativ hochwertige Software abzuliefern. Das ist auch der Anspruch, mit dem wir in unseren Projekten antreten. Und dafür ist es nicht verkehrt, auch 15 Jahre nach seinem Erscheinen sich mit diesem Buch auseinanderzusetzen.

Live Webinar: Softwareentwicklung skalieren, ohne sich im Wachstumsprozess aufzureiben

„Im Webinar wurden genau die Pain Points angesprochen, die in unserem Wachstum gerade auftreten. Bei stetig steigender Zahl an Mitarbeitern im Dev & Product Team mussten wir selbst feststellen, wie schwierig es ist, eine sinnvolle Struktur aufzubauen, die bei jedem das Maximum an Effizienz und Leistung hervorbringt und gleichzeitig zu einer gesunden Arbeitsatmosphäre führt.”
Pascal von Briel, Co-Founder & CPO @ Exporto GmbH