This article is also available in English
Eine kleine Anekdote
Ich erinnere mich an einen Workshop, in dem meine damaligen Kolleg:innen und ich aufgefordert wurden, unseren idealen Projekteinstieg aus Lego zu bauen. Was ich damals gebaut habe, weiß ich nicht mehr. Aber einer meiner Kollegen baute ein tiefes, braunes Grab. Auf die Frage, warum er darin das für ihn perfekte Projekt sehe, sagte er sinngemäß: „Wenn nicht hier und da ein paar Leichen vergraben sind, dann braucht es mich auch nicht.“ Ich komme also in ein neues Projekt und stolpere erst einmal in ein metertiefes Grab, um auf dem dunklen Grund zu tasten und zu schauen, wo die Leichen vergraben liegen? Eine schauderhafte Vorstellung! Für meinen Kollegen war das der perfekte Einstieg in ein Softwareprojekt.
Was ist Legacy-Code?
Oft sind die Vermächtnisse (engl. „legacies“) in Form von Code und Software, mit denen wir als Softwareentwickler:innen in Projekten konfrontiert werden, tatsächlich furchteinflößend. Unter Legacy-Code verstehe ich Code mit einigen Qualitätsmängeln, die dazu führen, dass der Code nur sehr schwer zu warten und zu erweitern ist. Qualitätsmängel, insbesondere technische Schulden, sind beispielsweise fehlende oder fragile Tests, eine hohe Komplexität, starke Kopplung zwischen Komponenten, nichtssagende Bezeichnungen und fehlende Dokumentation. Im schlimmsten Fall ist das ganze Softwaresystem ein sogenannter Big Ball of Mud, in dem die ursprünglich geplante Architektur und Struktur nicht einmal mehr zu erahnen ist. Häufig kommt hinzu, dass die Software veraltete Bibliotheken verwendet, welche aufgrund der starken Verflechtungen und fehlenden Tests nur sehr schwer aktualisiert werden können. Ein Nährboden für Sicherheitslücken entsteht. Die Wartungskosten steigen ins Unermessliche. Erweiterungen sind zeitaufwendig und fehleranfällig.
Es gibt aber auch noch eine andere Seite, die wir betrachten sollten: Denn Legacy-Systeme sind nicht nur vererbte (technische) Schulden, sondern in der Regel auch wertvolles Fachwissen und ausgeklügelte Prozessabläufe, die über Jahre hinweg in Software gegossen wurden. Häufig sind sie die Kernsysteme eines Unternehmens, die die großen Umsätze erwirtschaften. Dylan Beattie drückt dies mit seiner Definition von Legacy-Code sehr treffend aus: „Code that’s too scary to update and too profitable to delete.“ So betrachtet ist die große Schlammkugel vielmehr wertvoller Humus, der für reiche Erträge sorgt.
Wie kommt es zu Legacy-Code?
Vielfältige Gründe führen dazu, dass Code mit den Jahren immer schwerer zu warten ist. Es ist fast natürlich, dass das Hinzufügen neuer Funktionalität die Komplexität und den Grad der Unordnung erhöht. Vor allem, wenn es schnell gehen muss. Ivar Jacobson hat bereits 1992 dafür den Begriff der Software-Entropie geprägt. Sehr eindrücklich finde ich eine Visualisierung von Carola Lilienthal aus ihrem Buch „Langlebige Software-Architekturen“.
Hier wird deutlich, dass es aktive und kontinuierliche Anstrengungen braucht, um technische Schulden über einen längeren Zeitraum hinweg gering zu halten. Neben Wartung und Weiterentwicklung muss auch aktiv die zugrunde liegende Architektur regelmäßig an die neuen Gegebenheiten angepasst und verbessert werden. Geschieht dies nicht, explodieren früher oder später die Entwicklungskosten. Mangelnde Erfahrung und Zeitdruck beschleunigen den Prozess der Entropie. Gutes Design, Code-Reviews und regelmäßiges Refactoring wirken ihr entgegen.
Technische Schulden sind nur indirekt für Anwender:innen und Management sichtbar. Die mangelnde Sichtbarkeit sorgt dafür, dass notwendige Anpassungen in der Architektur und Struktur des Codes sowie Aktualisierungen der Bibliotheken oft nicht ausreichend priorisiert werden.
Ich möchte in diesem Artikel aber vor allem einige menschliche Aspekte beleuchten, die möglicherweise die Problematik verstärken. Aus ihnen ergibt sich allerdings auch ein großes Potenzial, wie wir zukünftig besser mit Legacy-Code umgehen können. Hierbei geht es um die Charaktere der Entwickler:innen, deren Vorlieben und Motivationen und um einige Vorurteile und Stereotypen, die uns auch in Bezug auf Legacy-Modernisierung manchmal Steine in den Weg legen.
Mit Legacy-Code möchte doch keiner etwas zu tun haben, oder?
Doch! Entgegen vieler Vorurteile und den gängigen Stereotypen für Softwareentwickler (hier spare ich mir das Gendern, weil an nicht-männliche Entwickler:innen in der Regel leider gar nicht erst gedacht wird) gibt es auch einige Menschen, die nicht gerne auf der grünen Wiese implementieren. Die nicht immer mit den neuesten Technologien arbeiten wollen, und die es nicht zufriedenstellend finden, 80-Prozent-Lösungen zu bauen. Mein Kollege hätte eine grüne Lego-Bauplatte als Sinnbild für den perfekten Projekteinstieg nehmen können, falls er das gewollt hätte.
Um diese Unterschiede zu zeigen, haben Andrea Goulet und M. Scott Ford ein Modell für unterschiedliche Charaktere von Entwickler:innen in Form einer Vierfeldermatrix entworfen.
Sie spannen das Feld der Softwareentwickler:innen in zwei Dimensionen auf: Auf der horizontalen Achse unterscheiden sie Hacker und Crafter, also die Charaktere, die etwas besonders schnell machen wollen, gegenüber denen, die etwas besonders sorgfältig machen wollen. Vertikal unterscheiden sie zwischen Makern, die etwas Neues erschaffen wollen, und Mendern, deren Leidenschaft es ist, bestehende Software zu verbessern, Strukturen anzupassen sowie Fehlern auf den Grund zu gehen. Menschen mit Crafter- und Mender-Vorlieben werden dem Quadranten der Software Remodeler zugeordnet. Genau diese Personen wären besonders geeignet für die Arbeit mit Legacy-Code. Aus dieser Erkenntnis heraus haben Andrea Goulet und M. Scott Ford vor einigen Jahren gemeinsam ein Unternehmen gegründet, welches auf die Modernisierung von Legacy-Systemen spezialisiert ist.
Es ist natürlich ein sehr vereinfachendes Modell für eine wesentlich vielschichtigere Welt. Aber sehen wir uns doch typische Situationen aus unserem Berufsalltag an: Wir sind häufig geneigt, uns als Entwickler:innen lediglich nach Technologien einzuordnen und dementsprechend passende Projekte zu wählen: „Machst du Frontend oder Backend? Java oder Python?“ Implizit nehmen wir an, dass dies die wichtigsten und größten Unterscheidungsmerkmale sind. Dabei sind Technologien lediglich angelerntes Wissen, welches schnell in die Jahre kommen oder erweitert werden kann. Mein inneres Wertegerüst und meine Persönlichkeitsmerkmale sind im Erwachsenenalter dagegen weitgehend stabil. Fragen wir doch einmal im Bewerbungsgespräch danach: „Bist du Mender oder eher Maker? Fühlst du dich in der schnellen Einsatztruppe oder bei der Neustrukturierung des Softwaresystems wohler?“ Auch Stellenausschreibungen verraten häufig nicht, welche Charaktereigenschaften gesucht werden.
So wie wir den Begriff Legacy-Code heute verstehen, würde wohl kaum ein:e Entwickler:in „Ich mag Legacy-Code!“ rufen. Vermutlich sind es sogar die Mender, die Ausbesserer, die das größere Grauen bekommen, wenn sie mit Legacy-Code konfrontiert werden. Komplizierte und veraltete Software will keiner. Aber während einige Menschen davor am liebsten weglaufen und eine Neuentwicklung vorschlagen, motiviert sie andere zum Aufräumen und Verbessern.
Software Remodeling ist keine leichte Aufgabe, vor allem dann nicht, wenn sie lange Zeit vernachlässigt wurde. Die Arbeit mit großen Legacy-Systemen erfordert umsichtiges und strukturiertes Vorgehen, tiefes Verständnis und viel Erfahrung. Nicht zuletzt brauchen große Modernisierungen in der Regel einen langen Atem. Es ist oft auch keine Arbeit, auf die man im Studium vorbereitet wird. Warum kommt diese Art von Arbeit, die ein solides Fundament für kontinuierliche Weiterentwicklung legt, nicht so gut an in unserer Entwicklungswelt?
Wo bleibt die Wertschätzung?
Ich habe bereits dargelegt, dass Softwareentwicklung weit mehr ist, als neue Funktionalitäten zu entwickeln; zumindest, wenn die Software unter angemessenen Kosten ein paar Jahre die Herausforderungen des Marktes bestehen soll (siehe Abbildung 1). In einer umfassenden Studie mit 334 IT-Entscheider:innen zum Thema Legacy-Modernisierung schätzten 57 Prozent der Firmen die Modernisierung ihrer geschäftskritischen Bestandssysteme als wichtig oder sehr wichtig ein. Trotzdem bekommt diese Art von Arbeit jenseits von neuen Features nach wie vor in den Projekten nur sehr wenig Aufmerksamkeit und Wertschätzung. Nicht selten habe ich in Projekten möglichst unbemerkt nebenbei versucht, die Liste an Bugs und technischen Schulden im Backlog abzuarbeiten, da diese nie ausreichend priorisiert wurden, um es ins Sprint-Backlog zu schaffen. Es ist für mich unerträglich zu sehen, wie meine tägliche Arbeit mehr und mehr Schulden verursacht.
Als Softwareentwickler:in ist es unattraktiv, sich offen als Mender zu positionieren. Nicht nur in der täglichen Care-Arbeit muss man mit weniger Aufmerksamkeit und Wertschätzung durch Manager:innen rechnen. Auch in Bewerbungsgesprächen befürchten viele zurecht schlechtere Chancen, wenn sie keine Kenntnisse in den neuesten Technologien, oder durch lange Projektlaufzeiten eine geringere Bandbreite an Technologien aufweisen können. Stefan Tilkov sagte dazu in der Veröffentlichung der eben erwähnten Studie zu Legacy-Modernisierung: „Neue Mitarbeiter haben oft keinen Bock, sich auf eine hinübergerettete, proprietäre Umgebung einzulassen und sich damit ihren Lebenslauf zu verderben.“ Auf der anderen Seite gebe es aber heute gerade auch jüngere Leute, die „sinnstiftende“ Dinge tun und zum Erfolg des Unternehmens beitragen wollen. Technologien sind kein Selbstzweck, sondern Werkzeuge für die passende Umsetzung eines Geschäftsmodells. Daher müssen wir dringend davon weg, nur auf die neuesten Trends und Technologien zu schauen, mit dem Ziel, diese in unseren Lebensläufen wie Trophäen vorzeigen zu können.
Das gängige Bild vom Softwareentwickler als Maker sorgt auch dafür, dass sich Menschen mit Mender-Qualitäten als defizitär, vielleicht sogar als unqualifiziert einschätzen. Die Stereotypen verleiten Menschen dazu, ihre Mender-Qualitäten zu leugnen. Schon die Art und Weise, wie uns Entwickler:innen Projekte angeboten werden, verrät, welche Projekte wir als cool und spannend auffassen sollen und für welche wir eher bemitleidet werden. Auch auf Entwicklungskonferenzen spielt Software Remodeling meist eine untergeordnete Rolle.
An dem Modell von Andrea Goulet und M. Scott Ford gefällt mir der Begriff „Software Remodeler“ sehr gut, weil er meiner Meinung nach wertneutral zwischen den anderen drei Rollen steht. Trotz aller intrinsischen Motivation, ohne extrinsische Anreize, laufen wir Gefahr, einige Mender, die wir dringend brauchen, zu verlieren.
Diversität gezielt nutzen!
Bei der Besetzung eines Entwicklungsteams lohnt es sich auch, auf die inneren Antriebe von Menschen zu achten, um ein passendes Verhältnis zwischen Mendern und Makern im Team zu haben. Ist das gegeben, stehen die Chancen gut, dass ein selbstorganisiertes Entwicklungsteam sowohl neue Features als auch den Abbau technischer Schulden angemessen priorisiert. Sicherlich kann jede:r Entwickler:in auch mal für Tätigkeiten außerhalb der Komfortzone eingesetzt werden. Wird das allerdings zur Regel, verschenken wir wertvolles Potenzial.
Folgende Spielart der oben eingeführten Vierfeldermatrix kann dabei helfen, eine für das jeweilige Projekt passende Teambesetzung zu finden.
Die Abbildung stellt einen Zusammenhang zwischen den uns bekannten Charakteren von Softwareentwickler:innen und vier Attributen her, welche einen hohen Einfluss auf den Erfolg eines Softwareprodukts haben können. Ist Geschwindigkeit ein wesentlicher Erfolgsfaktor des Projekts? Dann sind Entwickler:innen gefragt, die unter Zeitdruck effektiv und pragmatisch zu Lösungen kommen. Andere Kontexte verlangen einen weitaus risikoaverseren Entwicklungsstil. Projekte, die auf Langlebigkeit und hohe Qualität ausgelegt sind, profitieren von Entwickler:innen, die sorgfältig und ausdauernd Lösungen erarbeiten. Menschen, die sich als Crafter bezeichnen, fällt es häufig schwer, unter Zeitdruck effizient zu arbeiten, während Hacker-Persönlichkeiten auf der anderen Seite oft Schwierigkeiten haben über die 80-Prozent-Lösung hinaus an einer Sache dranzubleiben. Dreht sich das Projekt darum, mit Innovationen neue Kundensegmente zu erschließen, oder zielt es vielmehr darauf ab, bewährte Funktionalitäten zu verbessern und durch ein zuverlässiges Produkt die Anforderungen der Bestandskunden nach Stabilität zu erfüllen? Sicherlich gibt es hier keine Schwarz-Weiß-Antworten, vielmehr fordern unsere Produkte in der Regel alle vier Attribute mit unterschiedlicher Gewichtung. Nur mit einem diversen Team sind wir in der Lage, alle Bereiche abzudecken. Dabei können alle Charaktere im Team von den unterschiedlichen Arbeitsstilen lernen und finden im Diskurs das für das jeweilige Produkt richtige Maß.
Mit der Evolution von Softwareprodukten kommt noch ein weiterer Aspekt hinzu: In der Regel verschieben sich die Gewichtungen der vier Erfolgsfaktoren für ein Softwareprodukt mit der Zeit. Zu Beginn geht es typischerweise darum, ein neues Produkt so schnell wie möglich auf den Markt zu bringen, um frühzeitig Feedback einzuholen und die Geschäftsidee zu erproben. Ich selbst musste feststellen, dass es in dieser Phase keine gute Idee ist, zu viele Menschen im Team zu haben, deren Leidenschaften im Bereich Software Remodeling liegen. Geschwindigkeit und Mut zum Scheitern sind hier wichtiger als durchdachte Architekturen. Ist das Produkt erst einmal auf dem Markt, ist es wichtig, den Funktionsumfang zu erweitern, um Kunden zu gewinnen. Aber schon hier ist es notwendig, die Qualität nicht aus den Augen zu verlieren und Mender-Mentalitäten im Team zu positionieren. Auch wenn unsere Software einige Jahre später vor einem großen Modernisierungsprojekt steht, ist es sicherlich sinnvoll, parallel dazu den Kundenstamm weiterhin mit Erweiterungen und Innovationen zu versorgen. Die Mischung macht es also. Und es ist durchaus sinnvoll, die Teamzusammensetzung an sich ändernde Prioritäten anzupassen.
Oft scheitern Teams, die ein neues Softwareprodukt erfolgreich an den Markt gebracht haben, wenige Monate nach Markteinführung. Schnelle Reparaturen und Erweiterungen führen dazu, dass die Wartungskosten schnell ansteigen. Der Versuch, mit der gleichen Teambesetzung das Problem in den Griff zu bekommen, mündet nicht selten in einer Neuentwicklung. Nicht, weil es an dieser Stelle die sinnvollste Entscheidung ist, sondern weil eine Neuentwicklung den Neigungen und Fähigkeiten der Entwickler:innen entspricht.
Die richtige Balance bei der Teambesetzung zwischen Makern, Craftern, Mendern und Hackern am jeweiligen Evolutionspunkt der Software ist daher ein entscheidender Aspekt bei der Langlebigkeit der Software.