In most if not all legacy systems there is a treasure of domain knowledge that is worth to be dug out. That's why I agree a hundred percent with „treating legacy with respect“! These systems have become so old for a reason and that reason is that they did their job well (or at least well enough…).
Das oben Zitierte ist ein Kommentar von Henning Schwentner zu einer Aussage von Michael Plöd:
Always treat the legacy with respect. No one got up 20 years ago to build a bad system. To drive change, you need empathy first.
Mit „Legacy-Code“ meinen wir meistens Code, der über die Jahre technische Schulden angesammelt hat: Stellen, an denen jemand eine Abkürzung genommen, einen Workaround eingebaut oder eine Designentscheidung getroffen hat, die heute fragwürdig wirkt. Eine übliche Reaktion darauf ist Spott: „Wer schreibt denn so etwas?“
Diese Schulden entstehen in der Regel nicht aus Bosheit, Faulheit oder Unfähigkeit, sondern aus Bedingungen, die wir nicht miterlebt haben: knappe Termine, fehlende Informationen, Werkzeuge, die es damals so noch nicht gab. Die Frage „Wer schreibt denn so etwas?“ beantwortet sich meistens mit: jemand, der unter genau diesen Bedingungen das Beste versucht hat.
Im Code verborgene Geschichten
Der Entwickler, der vor 20 Jahren ein bestimmtes Framework gewählt hat, hat vermutlich nicht das schlechteste genommen, sondern eines, das damals als gute Wahl galt. Das Team, das die schnelle statt der sauberen Lösung gewählt hat, hat das oft getan, weil das Liefern in dieser Woche wichtiger war als die saubere Lösung in drei Wochen. Die Architektin, deren Entscheidungen heute seltsam wirken, hat sie unter Annahmen getroffen, die später nicht mehr gegolten haben.
Wer den Code abkanzelt, kanzelt damit auch die Menschen ab, die ihn geschrieben haben, und zwar ohne deren Einschränkungen zu kennen. Abgesehen vom Tonfall ist das auch praktisch ein Problem: Aus einer Haltung des Urteilens heraus übersehen wir die Informationen, die es bräuchte, um das System sinnvoll zu verbessern.
Andrea Goulet schreibt in Empathy-Driven Development:
Coding is a form of communication. Communication is rooted in empathy. So software engineers have a lot to gain from leveraging empathy as a tactical skill.
Empathie ist hier keine vage Tugend, sondern eine technische Fähigkeit, die wir durch bewusstes Üben lernen und verbessern können.
Statt „Warum ist das so gemacht?“ mit dem unausgesprochenen „... denn das ist Unsinn“ lohnt sich die Frage „Welches Problem sollte hier gelöst werden? Welche Einschränkungen waren im Spiel? Welches Wissen hatte die Person, das mir fehlt?“ Das verschiebt die eigene Position vom Urteilen zum Lernen und meistens finden wir dann auch tatsächlich etwas heraus.
Schreibe für die nächste Person
Die unangenehme Kehrseite ist: Der Code, den wir heute schreiben, ist die Legacy von morgen. Wer Empathie für vergangene Entscheidungen einfordert, sollte zukünftigen Lesenden des eigenen Codes dieselbe Empathie ermöglichen. Das ist im Wesentlichen eine Schreibaufgabe:
- Commit Messages, die das „Warum“ erklären, nicht nur das „Was“
- Pull-Request-Beschreibungen, die Überlegungen und Einschränkungen sichtbar machen
- Code-Kommentare an den Stellen, an denen die Entscheidung nicht offensichtlich aus dem Code hervorgeht
- Dokumentation, die das aktuelle Verhalten und die Annahmen dahinter festhält
- Tests, die nicht nur prüfen, was passiert, sondern auch, welche Randfälle warum wichtig sind
In einem früheren Artikel habe ich einige dieser Artefakte, beispielsweise etwa Architecture Decision Records und Technical Debt Records, genauer beschrieben.
Diese Dinge sind nicht Mehraufwand um des Mehraufwands willen. Sie sind die einzige Form, in der Kontext über Personalwechsel und Jahre hinweg überlebt. Wenn wir es richtig machen, muss die Person, die in zehn Jahren auf unseren Code stößt, ihn nicht erst entschlüsseln.