Kaum ein Begriff in der Softwareentwicklung ist so negativ aufgeladen wie "Legacy Code". Er klingt nach Altlast, nach Müll, nach etwas, das man am liebsten sofort wegwerfen möchte. Genau diese Reflexhaltung kostet Unternehmen jedes Jahr viel Geld, weil sie funktionierende Systeme voreilig zur Neuentwicklung verurteilen. In diesem Artikel bekommen Sie eine ehrliche Legacy Code Definition, die den Begriff vom emotionalen Ballast befreit und Ihnen hilft, eine bessere Entscheidung zu treffen.
Legacy Code Definition: Was der Begriff wirklich bedeutet
Legacy Code ist Code, den Sie geerbt haben und den Sie nur mit Unsicherheit verändern können. Das ist der Kern. Es geht nicht um das Alter, nicht um die eingesetzte PHP-Version und auch nicht um den Programmierstil an sich, sondern um Ihre Fähigkeit, das System gefahrlos anzupassen.
Michael Feathers hat in seinem Standardwerk "Working Effectively with Legacy Code" eine bewusst provokante Definition geprägt: Legacy Code ist schlicht Code ohne Tests. Ich finde diese Zuspitzung hilfreich, weil sie den Finger in die richtige Wunde legt. Ohne automatisierte Tests wissen Sie nach jeder Änderung nicht, ob Sie etwas kaputt gemacht haben. Jede noch so kleine Anpassung wird zum Risiko. Genau dieses Gefühl der Unsicherheit ist das definierende Merkmal von Legacy Code.
In der Praxis kommt selten nur ein Faktor allein vor. Ein typisches Legacy-PHP-System hat mehrere dieser Eigenschaften:
- Keine oder kaum automatisierte Tests
- Fachlogik, die eng mit der Datenbank oder der HTML-Ausgabe verwoben ist
- Ein oder zwei Personen, die "wissen, wie es läuft" und deren Wissen nirgends dokumentiert ist
- Veraltete Abhängigkeiten, die sich nicht mehr per Composer aktualisieren lassen
- Fehlende oder falsche Dokumentation, die niemand mehr pflegt
Warum "alt" nicht "schlecht" bedeutet
Ein System, das seit acht oder zwölf Jahren im produktiven Einsatz ist, wird gern belächelt. Dabei sollte genau das Gegenteil passieren. Ein laufendes System ist der beste Beweis dafür, dass die Fachlogik funktioniert. Es hat unzählige echte Geschäftsvorfälle verarbeitet, Randfälle abgefangen, die in keinem Konzept standen, und gesetzliche Änderungen überlebt.
Diese jahrelang gewachsene Fachlogik ist bares Kapital. In den Verzweigungen, die auf den ersten Blick chaotisch wirken, stecken oft Jahre an Wissen: Warum wird bei einem bestimmten Kundentyp der Rabatt anders berechnet? Warum gibt es diese eine merkwürdige Ausnahme bei der Rechnungsstellung? Diese Regeln sind meist nicht dokumentiert, aber sie sind korrekt, weil sie sich in der Realität bewährt haben. Wer neu entwickelt, wirft dieses Wissen weg und muss es mühsam neu ausgraben.
Das eigentliche Problem ist selten die Fachlogik
Wenn ein Legacy-System weh tut, liegt das fast nie an der Fachlogik selbst. Das Problem ist der Code drumherum. Die Berechnung des Deckungsbeitrags ist meist völlig in Ordnung. Was fehlt, ist die saubere Trennung: Dieselbe Methode holt Daten aus der Datenbank, rechnet, formatiert das Ergebnis und gibt gleich noch HTML aus.
Diese fehlende Trennung, oft als "Spaghetti-Code" bezeichnet, ist das eigentliche Wartungsproblem. Sie macht Änderungen riskant, weil alles mit allem verbunden ist. Ein konkretes Beispiel aus vielen PHP-Projekten:
Eine 800 Zeilen lange Datei enthält SQL-Abfragen per
mysql_query(), Geschäftsregeln,echo-Ausgaben und HTML in einem einzigen Durchlauf. Die Rabattlogik darin ist korrekt. Man kommt nur nicht mehr an sie heran, ohne zehn andere Dinge zu berühren.
Der entscheidende Punkt: Fachlogik und struktureller Zustand sind zwei getrennte Dinge. Sie können eine hervorragende, wertvolle Fachlogik in einer schlecht strukturierten Hülle haben. Die Aufgabe ist dann nicht, die Logik neu zu erfinden, sondern die Hülle Stück für Stück zu erneuern und die Logik dabei freizulegen.
Warum Neuentwicklung meist die teuerste Option ist
Der Reflex "Wir schreiben es neu" ist verständlich, aber in den meisten Fällen die riskanteste und teuerste Entscheidung. Dafür gibt es handfeste Gründe.
Bei einer Neuentwicklung starten Sie nicht bei null, sondern im Minus. Sie müssen zunächst all das nachbauen, was das alte System bereits kann, inklusive der undokumentierten Sonderfälle. Solange die Neuentwicklung läuft, bekommt das alte System keine Verbesserungen mehr, und Ihr Betrieb steht still, was neue Funktionen angeht. Der berühmte "Big Bang", bei dem am Stichtag umgeschaltet wird, geht überraschend oft schief, weil sich in der Praxis Regeln zeigen, an die niemand gedacht hatte.
Die realistische Alternative ist die schrittweise Modernisierung. In der Symfony- und Laravel-Welt gibt es dafür bewährte Muster:
- Tests zuerst: Bevor Sie etwas ändern, schreiben Sie sogenannte Charakterisierungstests, die das aktuelle Verhalten festhalten, auch das vermeintlich falsche.
- Strangler-Fig-Muster: Neue oder überarbeitete Teile laufen neben dem Altsystem und übernehmen nach und nach dessen Aufgaben, bis das Alte verschwindet.
- Fachlogik isolieren: Sie ziehen die Geschäftsregeln aus den Controllern und Templates in klar abgegrenzte Services, ohne sie inhaltlich zu verändern.
- Abhängigkeiten aktualisieren: Composer-Pakete und die PHP-Version werden kontrolliert und in kleinen Schritten angehoben, jeweils mit Tests abgesichert.
Ist mein System Legacy Code? Eine ehrliche Selbsteinschätzung
Ihr System ist Legacy Code, wenn Sie sich vor Änderungen fürchten, nicht wenn es einfach nur alt ist. Stellen Sie sich ehrlich diese Fragen: Trauen Sie sich, eine kleine Anpassung ohne Bauchschmerzen einzuspielen? Wissen mehr als zwei Personen, wie eine bestimmte Berechnung funktioniert? Können Sie eine veraltete Abhängigkeit aktualisieren, ohne dass etwas Unerwartetes passiert?
Wenn Sie hier mehrfach zögern, arbeiten Sie mit Legacy Code. Das ist kein Urteil über Ihre Software und kein Grund zur Panik. Es ist eine Bestandsaufnahme. Und die gute Nachricht steckt bereits in der Definition: Wenn Unsicherheit das Problem ist, dann ist Sicherheit die Lösung, und Sicherheit lässt sich mit Tests und sauberer Trennung gezielt herstellen.
Praxis-Tipp zum Schluss
Verwerfen Sie den Gedanken, dass Ihr laufendes System wertlos ist, weil es alt aussieht. Bevor irgendjemand über eine Neuentwicklung spricht, sollten Sie eine einzige Frage beantworten: Was genau tut weh, die Fachlogik oder der Code drumherum? In neun von zehn Fällen ist es Letzteres, und das lässt sich reparieren, ohne das wertvolle Wissen wegzuwerfen. Beginnen Sie mit einem Charakterisierungstest für den Bereich, der Ihnen die meisten Sorgen macht. Allein dieser erste Test verwandelt einen Teil Ihres Systems von "gefährlich" in "veränderbar".
Genau bei dieser Einschätzung und der schrittweisen Modernisierung von Legacy-PHP-Anwendungen unterstützt LegacyWerk, ehrlich und ohne den vorschnellen Ruf nach dem großen Neuanfang.