Das Bild zeigt fünf Holzklötze mit Symbolen für zwischenmenschliche Fähigkeiten. Eine Hand hebt dabei gezielt den Würfel mit dem roten Herz und der Aufschrift "EMPATHY" hervor. Die warme, ruhige Stimmung unterstreicht Empathie als technische Fähigkeit in der Softwareentwicklung.

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.

Diese beiden Aussagen, die vor kurzem von zwei angesehenen Stimmen aus dem Bereich Softwarearchitektur auf LinkedIn geteilt wurden, haben mehr als nur eine einfache professionelle Beobachtung angesprochen. Sie haben eine Wahrheit ausgesprochen, die oft vergessen wird, wenn wir uns mit komplexen Codebasen und architektonischen Herausforderungen beschäftigen: Technische Schulden sind nicht böswillig. Sie sind nicht aus böser Absicht, Faulheit, Unfähigkeit oder Nachlässigkeit entstanden. Vielmehr sind sie das Ergebnis einer Anhäufung von Einschränkungen, Kompromissen und Umständen, die wir nicht miterlebt haben.

Im Laufe der Jahre habe ich gelernt, dass die wertvollste Fähigkeit in der Softwareentwicklung nicht architektonische Meisterschaft oder technische Virtuosität ist. Es ist Empathie. Genauer gesagt ist es die Fähigkeit, nicht mit Verachtung zu fragen: „Was haben sich diese Entwicklerinnen und Entwickler dabei gedacht?“, sondern stattdessen zu fragen: „Welches Problem haben sie zu lösen versucht? Unter welchen Einschränkungen haben sie gearbeitet? Warum war ihre Lösung zu diesem Zeitpunkt die beste Wahl?“

Im Code verborgene Geschichten

Jede Zeile Legacy-Code ist das Ergebnis der besten Bemühungen von Menschen, ein echtes Problem mit den Tools, dem Wissen und den Einschränkungen zu lösen, die ihnen damals zur Verfügung standen. Bedenke den Kontext: Eine Entwicklerin oder ein Entwickler hat 2006 ein bestimmtes Framework gewählt, weil es damals das Neueste war. Oder ein Team, das unter ständigem Termindruck stand und sich für die schnelle Lösung statt für die sauberere entschieden hat, weil das Liefern in dieser Woche wichtiger war. Oder eine Architektin bzw. ein Architekt, die bzw. der eine Designentscheidung getroffen hat, die angesichts der geschäftlichen Einschränkungen und der technischen Gegebenheiten jener Zeit völlig vernünftig war.

Wenn wir diesen Systemen mit Neugier statt mit Verachtung begegnen, offenbaren sie uns ihre Geschichte. Wir entdecken organisatorische Prioritäten, die sich mitten im Projekt verschoben haben. Wir decken Technologien auf, die vielversprechend schienen, aber nicht funktioniert haben. Wir finden architektonische Entscheidungen, die vollkommen sinnvoll waren, bevor das Unternehmen eine neue Richtung eingeschlagen hat. Wir sehen die Spuren von Menschen, denen die Lösung von Problemen genauso am Herzen lag wie uns.

Doch in viel zu vielen Code Reviews und Teamdiskussionen höre ich eine andere Erzählung: Ablehnung, getarnt als Kritik. Entwicklerinnen und Entwickler spotten über Legacy-Systeme, ohne zu bedenken, dass die Ablehnung des Codes im Grunde genommen eine Ablehnung der Menschen ist, die ihn geschrieben haben. Sie geben den Menschen, die vor ihnen an der Software gearbeitet haben, die Schuld, ohne die Einschränkungen zu berücksichtigen, mit denen diese konfrontiert waren.

Das Problem ist nicht nur der Tonfall. Dieser auf Schuldzuweisungen ausgerichtete Ansatz ist sogar kontraproduktiv. Wenn wir von einer wertenden Haltung ausgehen, übersehen wir wichtige Infos, die wir brauchen, um das System sinnvoll zu verbessern. Wir verpassen die Chance, das in der Codebasis enthaltene Fachwissen zu nutzen, das vielleicht unersetzlich und unglaublich wertvoll ist.

Empathie als technische Fähigkeit

Die Softwarebranche hat Empathie viel zu lange „nur“ als einen Soft Skill angesehen: etwas, das zwar nett ist, aber für technische Exzellenz nicht so wichtig ist. Das ist aber ein Fehler, der aus einem grundlegenden Missverständnis darüber entsteht, was Empathie eigentlich ist.

Empathie ist nicht nur ein Gefühl. Es ist eine technische Fähigkeit, die wir durch bewusstes Üben lernen und verbessern können. Andrea Goulet beschreibt sie in Empathy-Driven Development als „proaktives Einnehmen von Perspektiven und Problemlösen“. Diese Definition macht Empathie von etwas Abstraktem und Ungreifbarem zu etwas Konkretem und Umsetzbarem. Bevor du eine Entscheidung triffst, nimm dir einen Moment Zeit, um zu überlegen, wer davon betroffen sein wird und was diese Personen von dir brauchen könnten.

Wenn wir diesen Ansatz auf Legacy-Code anwenden, führen wir eher eine Untersuchung durch als eine Kritik. Wir fragen: „Welche Kompromisse ist diese Person eingegangen?“, „Mit welchen Einschränkungen musste sie umgehen?“, „Über welches Wissen verfügt sie, das mir fehlt?“ Durch diese Fragen wechseln wir von einer überlegenen Haltung in eine lernende Haltung.

Das ist keine Sentimentalität. Es ist Pragmatismus. Die Systeme, die wir übernehmen, laufen seit Jahren oder sogar Jahrzehnten in der Produktion, gerade weil sie ihren Zweck gut (genug) erfüllen. Sie haben ein Verständnis für Geschäftsregeln, Randfälle und organisatorische Nuancen aufgebaut, das im Code und im kollektiven Gedächtnis der Teams vorhanden ist, die sie entwickelt und gewartet haben. Wenn wir Legacy-Systeme mit Respekt statt mit Verachtung behandeln, können wir auf dieses Wissen zugreifen. Wir können dieses Wissen dann extrahieren und daraus lernen, um in Zukunft bessere Systeme zu entwickeln.

Technische Schulden verstehen

Technische Schulden entstehen nicht einfach, weil frühere Entwicklerinnen oder Entwickler inkompetent oder gleichgültig waren. Sie entstehen aufgrund der realen Einschränkungen, mit denen Softwareteams täglich konfrontiert sind.

Betrachten wir einmal den Entscheidungsbaum, mit dem eine Entwicklerin oder ein Entwickler konfrontiert ist: Soll sie oder er die Funktion rechtzeitig liefern, indem eine Abkürzung genommen wird, oder soll die Funktion ordnungsgemäß entwickelt werden, wodurch möglicherweise die Frist verpasst wird – und damit vielleicht das Marktfenster, das die Funktion wertvoll macht? Das sind keine rein technischen Entscheidungen. Es sind menschliche Entscheidungen, die im organisatorischen Kontext getroffen werden. Sie beinhalten konkurrierende Prioritäten, Budgetbeschränkungen, Zeitdruck und die in jedem Team unvermeidlichen Wissenslücken.

Entwicklerinnen und Entwickler, die sich für pragmatische Lösungen entscheiden, schreiben nicht nur Code, auf den sie stolz sein können. Sie lösen ein geschäftliches Problem innerhalb realer Einschränkungen. Jahre später, wenn sich der geschäftliche Kontext geändert hat, mag diese Entscheidung töricht erscheinen. Aber zu diesem Zeitpunkt war es oft die richtige Entscheidung – oder zumindest die einzige Entscheidung, die sie treffen konnten.

Diese Erkenntnis sollte unsere gesamte Herangehensweise an technische Schulden verändern. Es handelt sich nicht um ein moralisches Versagen. Es ist die natürliche Folge davon, dass Software in der realen Welt bereitgestellt werden muss, wo das Streben nach Perfektion den Fortschritt behindern kann und wo es darauf ankommt, Dinge auf den Markt zu bringen.

Ein Weg nach vorn

Wenn technische Schulden nicht böswillig sind, sollten wir nicht mit Schuldzuweisungen reagieren. Wir müssen mit Verständnis reagieren.

Diese Veränderung hat tiefgreifende Auswirkungen auf unsere Arbeitsweise. Wenn eine Entwicklerin oder ein Entwickler über ein Altsystem spottet und sagt: „Das hätte so nie gemacht werden sollen“, ist das keine hilfreiche Kritik. Sie zeigen damit, dass sie den Kontext, in dem der Code geschrieben wurde, nicht verstehen. Noch wichtiger ist, dass sie damit die Tür zu genau dem Verständnis schließt, das wir brauchen, um voranzukommen.

Wenn wir auf verwirrenden Code stoßen, ist die wertvollste Frage, die wir stellen können, nicht „Warum wurde das so gemacht?“, sondern „Welches Problem sollte damit gelöst werden?“ Durch diese Umstellung von Urteilsvermögen auf Neugierde werden ganz andere Gespräche eröffnet. Sie lädt erfahrene Kolleginnen und Kollegen ein und ermutigt sie, ihr Wissen zu teilen. Sie hilft jüngeren Entwicklerinnen und Entwicklern, nicht nur zu verstehen, was der Code macht, sondern auch, warum er existiert. So entsteht Raum für echtes Lernen.

Das Gleiche gilt für die Art und Weise, wie wir heute Code schreiben. Wenn wir uns für Empathie gegenüber Legacy-Systemen einsetzen, müssen wir uns fragen, unter welchen Einschränkungen wir arbeiten und ob unser zukünftiges Ich oder unsere Nachfolger die gleiche Empathie verdienen. Welche Kompromisse gehen wir ein? Welches Problem lösen wir, und was muss jemand, der diesen Code liest, in fünf Jahren über unsere Entscheidung wissen?

Mit Empathie entwickeln

Bei der Wertschätzung von Legacy-Code geht es um mehr als nur um Höflichkeit. Sie bildet die Grundlage für die Weiterentwicklung nachhaltiger Software. Wenn wir Systeme mit Empathie angehen, verwandeln wir unsere Beziehung zur Codebasis von einer feindseligen in eine kooperative. Anstatt zu fragen „Sollten wir das umschreiben?“, fragen wir „Was müssen wir über dieses System wissen, bevor wir es verbessern können?“. Wir verwandeln einen anspruchsvollen Modernisierungsprozess in eine Gelegenheit zum Wissenstransfer.

Dafür braucht es bestimmte Vorgehensweisen:

  • Gut formulierte Commit Messages, die nicht nur das „Was“, sondern auch das „Warum“ erklären
  • Pull Request-Kommentare, die Denkprozesse und Einschränkungen aufzeigen
  • Code-Kommentare, die nicht offensichtliche Entscheidungen verdeutlichen
  • Dokumentation, die das Verhalten des aktuellen Systems und das Wissen derjenigen erfasst, die es entwickelt haben
  • Tests, die das erwartete Verhalten und die wichtigen Randfälle erklären

In einem früheren Artikel habe ich einige dieser Artefakte, beispielsweise Architecture Decision Records und Technical Debt Records, näher beleuchtet.

Diese Artefakte sind kein lästiger Mehraufwand. Sie sind Zeichen von Empathie. Sie ermöglichen es dir, mit einer zukünftigen Entwicklerin oder einem zukünftigen Entwickler ins Gespräch zu kommen und ihnen nicht nur zu zeigen, was dein Code macht, sondern auch, warum du ihn so entwickelt hast, wie du es getan hast.

Das gleiche Prinzip gilt auch für die Organisation unserer Arbeit und unserer Teams. Wenn wir Legacy-Systeme als Wissensspeicher betrachten und nicht als Probleme, die es zu beseitigen gilt, bewahren wir das darin enthaltene Wissen. Wir vermeiden die immense Verschwendung, die mit dem Neuschreiben von Code einhergeht, der einwandfrei funktioniert. Wir schaffen Raum für schrittweise Verbesserungen. Und wir würdigen die Menschen, die das geschaffen haben, was wir geerbt haben.

Der Spiegel unserer Zukunft

Die wichtigste Erkenntnis ist: Die Systeme, die wir heute bauen, sind die Legacy von morgen. Der Code, den wir jetzt schreiben, wird von Entwicklerinnen und Entwicklern gepflegt werden, die wir nie treffen werden. Die Architekturentscheidungen, die wir heute treffen, werden Teams in fünf, zehn oder sogar fünfzehn Jahren entweder einschränken oder befähigen.

Unser zukünftiges Ich sowie die, die nach uns kommen, verdienen die gleiche Empathie, für die wir uns heute einsetzen. Das bedeutet, dass wir Tests schreiben müssen, die nicht nur erklären, was der Code macht, sondern auch, warum er auf eine bestimmte Weise geschrieben wurde. Es bedeutet, dass wir die Einschränkungen dokumentieren müssen, unter denen wir gearbeitet haben, und anerkennen müssen, dass unsere Entscheidungen menschliche Entscheidungen waren, die im organisatorischen Kontext getroffen wurden, und niemals rein technische Entscheidungen, die isoliert getroffen wurden. Wir müssen der Versuchung widerstehen, unsere Arbeit als unvermeidliches Ergebnis reiner Logik darzustellen, wenn wir in Wirklichkeit immer Kompromisse eingehen, die von geschäftlichen Prioritäten, Termindruck, verfügbarem Fachwissen und unzähligen anderen menschlichen Faktoren beeinflusst sind.

Vor allem bedeutet es, eine Kultur zu fördern, in der Empathie unseren Umgang mit Code, unsere Betreuung von Teamkollegen und unser berufliches Wachstum als Entwicklerinnen und Entwickler prägt. Es verwandelt „alles neu schreiben“ in „verstehen, dann strategisch verbessern“. Es verwandelt kontroverse Code Reviews in einen kooperativen Wissenstransfer. Es erinnert uns daran, dass wir nicht nur Maschinen manipulieren. Wir setzen einen Dialog mit anderen Menschen fort, denen die Lösung von Problemen genauso am Herzen liegt wie uns.

Empathie als technische Exzellenz

Empathie ist nicht das Gegenteil von technischer Exzellenz. Es ist sogar die Grundlage dafür. Die technisch versiertesten Entwicklerinnen und Entwickler verstehen nicht nur, wie Systeme funktionieren, sondern auch, warum sie existieren. Sie wissen, dass nachhaltige Software nicht durch individuelle Virtuosität entsteht, sondern durch kollektives Wissen, klare Kommunikation und Respekt vor der bisherigen Arbeit.

Wenn wir Legacy-Code mit dem Respekt behandeln, den Michael Plöd fordert, sind wir nicht sentimental. Wir sind strategisch. Wir wissen, dass das in bestehenden Systemen eingebettete Fachwissen unschätzbar ist, dass die Einschränkungen, mit denen diese Systeme zu kämpfen hatten, immer noch relevant sind und dass diejenigen, die sie entwickelt haben, uns etwas beibringen können.

Der Weg nach vorne für jedes Team besteht nicht darin, den Code, den es geerbt hat, abzulehnen oder zu verachten. Vielmehr sollte es bessere Fragen stellen. Es sollte sich dem Code mit Neugierde nähern. Es muss das darin enthaltene Wissen extrahieren. Es muss die Einschränkungen verstehen, die ihn geprägt haben. Auf dieser Grundlage können sie den Code dann schrittweise, durchdacht und mit Empathie für diejenigen, die vor ihnen kamen und denen, die nach ihnen kommen werden, verbessern.

So entwickeln wir Software, die Bestand hat. So ehren wir die Menschen hinter dem Code. So stellen wir auch sicher, dass die Systeme, die wir heute entwickeln, mit dem gleichen Respekt und Verständnis behandelt werden, wenn sie morgen zum Vermächtnis werden.