Legacy-Software modernisieren, ohne das System anzuhalten
Legacy-Software modernisieren, ohne das System anzuhalten
Artikel-Übersicht
Vorweg eine Klarstellung, weil der Begriff doppelt belegt ist: Migration meint hier den Umzug oder Umbau von Software — nicht das gesellschaftspolitische Thema, das Suchmaschinen in dieselbe Ergebnisliste mischen.
Dieser Artikel behandelt das, was in der Praxis den größten Teil der Architekturarbeit ausmacht und über das am wenigsten geschrieben wird: ein laufendes System umbauen, während es weiterläuft. Er definiert Legacy über Änderungsangst statt über Alter, trennt Migration von Modernisierung und Ersatz und geht die gängigen Strategien mit Aufwand und Risiko durch. Der Kern ist das schrittweise Ablösen nach dem Strangler-Muster in vier Schritten, mit den Kosten des Parallelbetriebs, die sonst niemand nennt. Dazu Charakterisierungstests für Systeme ohne Testabdeckung, die Datenmigration als eigentlicher Scheiterungsgrund, und eine ehrliche Einordnung dessen, was KI beim Verstehen von Altcode leistet.
Was Legacy eigentlich heißt
Legacy ist Software, die produktiv läuft und die niemand mehr gern ändert — unabhängig von ihrem Alter.
Diese Definition weicht bewusst von der üblichen ab. Ein zwölf Jahre altes System mit guter Testabdeckung, klarer Struktur und aktiver Pflege ist kein Legacy-System. Ein achtzehn Monate altes System, das drei Personen gebaut haben, die alle nicht mehr da sind, und bei dem niemand weiß, was passiert, wenn man etwas anfasst — das ist eines.
Das Kriterium ist die Änderungsangst, und sie hat handfeste Ursachen: fehlende Tests, fehlende Dokumentation, fehlendes Wissen über Sonderfälle, unklare Abhängigkeiten. Alle vier sind behebbar; das Alter ist es nicht.
Die Unterscheidung ist praktisch relevant, weil sie die Maßnahme bestimmt. Gegen Alter hilft nur Ersatz. Gegen Änderungsangst hilft ein Sicherheitsnetz.
Migration, Modernisierung, Ersatz
Drei Begriffe, die durcheinandergehen:
| Was passiert | Fachlichkeit | Risiko | |
|---|---|---|---|
| Migration | dasselbe System, andere Umgebung | unverändert | mittel |
| Modernisierung | dasselbe System, umgebaut | unverändert bis leicht erweitert | mittel bis hoch |
| Ersatz | neues System | wird neu erarbeitet | hoch |
Der häufigste Planungsfehler ist, das eine anzukündigen und das andere zu tun: eine Migration, bei der „gleich noch" die Fachlichkeit überarbeitet wird. Damit vervielfacht sich das Risiko, weil bei einem Fehler unklar ist, ob er vom Umzug oder von der Änderung kommt.
Die Regel: Umzug und Umbau nicht im selben Schritt. Erst umziehen, prüfen, stabilisieren — dann umbauen. Oder umgekehrt. Nie beides zugleich.
Die Arten von Migration
Die verbreitete Einteilung nach Umbautiefe:
| Strategie | Was passiert | Aufwand | Wann sinnvoll |
|---|---|---|---|
| Erneut hosten | unverändert auf neue Infrastruktur | gering | Rechenzentrumsumzug, Ende der Hardwareunterstützung |
| Anpassen | kleine Änderungen für die neue Umgebung | gering bis mittel | Containerisierung, verwalteter Datenbankdienst |
| Überarbeiten | Architektur ändern, Fachlichkeit behalten | hoch | Skalierung, Wartbarkeit |
| Neu bauen | von Grund auf, gleiche Fachlichkeit | sehr hoch | Technologiebasis abgekündigt |
| Ersetzen | Standardsoftware statt Eigenentwicklung | mittel | Fachlichkeit ist nicht differenzierend |
| Behalten | nichts tun, bewusst | keiner | läuft, ändert sich nicht, kein Risiko |
| Ausmustern | abschalten | gering | wird nicht mehr gebraucht |
Die beiden letzten Zeilen sind ernst gemeint und werden am häufigsten übersehen. Vor jeder Modernisierung sollte die Frage stehen, ob das System überhaupt noch gebraucht wird. In gewachsenen Landschaften findet man regelmäßig Anwendungen, die niemand mehr benutzt — sie zu modernisieren wäre die teuerste aller Optionen.
Modernisieren oder ersetzen?
Die Entscheidung, bei der die meisten Bauchgefühle im Spiel sind. Vier Kriterien:
Wie viel Wissen steckt undokumentiert im System? Das ist das wichtigste Kriterium. In einem zwanzig Jahre alten Abrechnungssystem stecken hunderte Sonderfälle, die niemand aufgeschrieben hat — Ausnahmen für bestimmte Kundengruppen, Übergangsregeln aus alten Gesetzesänderungen, Korrekturen für Fehler, die es einmal gab.
Ist die Fachlichkeit stabil? Wenn sie sich ohnehin grundlegend ändert, spricht mehr für einen Neubau. Wenn sie seit Jahren gleich ist, ist der Neubau reine Nachbildung — mit hohem Risiko und ohne fachlichen Gewinn.
Gibt es Tests? Oder lassen sie sich herstellen?
Wie lange müsste parallel gelaufen werden? Ein Neubau, der zwei Jahre dauert, bedeutet zwei Jahre doppelte Pflege — jede fachliche Änderung muss in beiden Systemen umgesetzt werden.
Und der Erfahrungssatz, der fast immer zutrifft: Der Neubau dauert länger als geschätzt und liefert weniger als erhofft. Der Grund ist immer derselbe — die undokumentierten Sonderfälle. Sie sind die eigentliche Spezifikation, und sie werden erst sichtbar, wenn das neue System produktiv geht und Dinge nicht mehr funktionieren, von denen niemand wusste, dass sie funktionierten.
Wie man Refactoring innerhalb eines Systems angeht und wann es die bessere Antwort ist, steht in Technische Schulden und Refactoring.
Schrittweise ablösen: das Strangler-Vorgehen
Der Name stammt von Martin Fowler und geht auf die Würgefeige zurück — eine Pflanze, die einen Baum umwächst, bis der Baum verschwindet und die Feige allein steht. Das Bild trägt: Das neue System wächst um das alte herum, Funktion für Funktion, bis vom alten nichts mehr übrig ist.
Vier Schritte:
1. Eine Fassade davorstellen. Aller Verkehr läuft künftig über eine Zwischenschicht, die zunächst nur weiterleitet. Für sich genommen ändert das nichts — es schafft den Ort, an dem später umgeleitet wird.
2. Eine Funktion herauslösen und umleiten. Ein Bereich wird im neuen System nachgebaut, die Fassade leitet die entsprechenden Aufrufe dorthin. Alles andere läuft weiter wie bisher.
3. Daten synchron halten. Der schwierigste Teil. Solange beide Systeme laufen, müssen die Daten in beiden stimmen — entweder durch Replikation oder dadurch, dass genau eines der beiden für einen Datenbereich zuständig ist.
4. Alte Implementierung abschalten. Erst wenn der neue Weg nachweislich funktioniert. Und dann tatsächlich abschalten, nicht „vorerst deaktiviert" liegen lassen.
Die Kosten, die niemand nennt
Das Strangler-Vorgehen ist das risikoärmste Verfahren und nicht das billigste. Was es kostet:
- Doppelte Pflege auf Zeit. Fachliche Änderungen an noch nicht abgelösten Bereichen müssen weiterhin im Altsystem gemacht werden.
- Doppelte Datenhaltung. Mit allem, was dazugehört: Abgleich, Konfliktbehandlung, Überwachung.
- Umschaltrisiko bei jedem Schritt. Zwar klein je Schritt, aber es gibt viele Schritte.
- Die Fassade selbst ist eine Komponente, die gebaut, betrieben und überwacht werden muss.
- Durchhaltevermögen. Der häufigste Grund für das Scheitern ist nicht ein technisches Problem, sondern dass das Vorhaben nach dem dritten von zwölf Schritten für dringendere Dinge unterbrochen und nie wieder aufgenommen wird. Zurück bleibt ein System, das halb im alten und halb im neuen Zustand ist — schlechter als beide Ausgangslagen.
Wo man anfängt
Nicht beim Schwierigsten und nicht beim Unwichtigsten. Die Auswahl folgt zwei Kriterien:
Hohe Änderungslast — dort zahlt sich die Ablösung am schnellsten aus. Die Auswertung dafür ist dieselbe wie bei technischen Schulden: Änderungshäufigkeit aus der Versionshistorie gegen Komplexität.
Klare Grenze — ein Bereich mit wenigen, gut verstandenen Abhängigkeiten zum Rest. Wenn die Modulgrenzen aus der Zeit vor der Ablösung stimmen, ist dieser Schritt einfach; wenn nicht, ist das Ziehen der Grenze der erste Teil der Arbeit. Wie man Grenzen fachlich schneidet, steht in Domain-Driven Design in der Praxis; der Zielzustand ist meist der in Microservices oder Monolith beschriebene modulare Monolith, nicht sofort eine verteilte Landschaft.
Charakterisierungstests: das Sicherheitsnetz
Für Systeme ohne Tests — also die meisten Legacy-Systeme — gibt es einen etablierten Ausweg.
Ein Charakterisierungstest beschreibt nicht, was der Code tun soll, sondern was er tatsächlich tut. Man ruft eine Funktion mit repräsentativen Eingaben auf, schreibt das tatsächliche Ergebnis als erwarteten Wert fest und hat damit ein Netz, das jede Verhaltensänderung sichtbar macht.
def test_rabattberechnung_charakterisierung():
# Kein Soll-Verhalten — nur das, was das System heute tut
assert berechne_rabatt(kundengruppe="B", umsatz=5000, jahr=2027) == 412.50
assert berechne_rabatt(kundengruppe="B", umsatz=4999, jahr=2027) == 0.00Der zweite Fall sieht aus wie ein Fehler — ein Euro weniger Umsatz, und der Rabatt fällt auf null. Vielleicht ist es einer. Beim Refactoring wird er trotzdem festgeschrieben, denn das Ziel ist, das Verhalten unverändert zu lassen. Ob der Sprung fachlich gewollt ist, klärt man getrennt und ändert ihn in einem eigenen Schritt.
Genau dieses Gefühl — falsches Verhalten festzuschreiben — ist der Grund, warum viele das Verfahren nicht anwenden. Es ist trotzdem richtig: Man kann nicht gleichzeitig umbauen und korrigieren und hinterher wissen, woher ein Fehler kommt.
Der praktische Weg, um die Eingaben zu finden: Produktivdaten in anonymisierter Form durch die alte Funktion schicken und die Ergebnisse aufzeichnen. Das erzeugt in einer Stunde mehr Testfälle, als man von Hand in einer Woche schreibt.
Datenmigration
Der Teil, der Projekte tatsächlich zum Scheitern bringt. Vier Punkte:
Abgleich vor der Umstellung. Alte und neue Datenhaltung parallel befüllen und die Ergebnisse vergleichen — über Wochen, nicht über Stunden. Die Abweichungen, die dabei auftauchen, sind der eigentliche Ertrag.
Testlauf mit Produktivdaten. Ein Migrationsskript, das nur an Testdaten erprobt wurde, ist nicht erprobt. In Produktivdaten stecken leere Felder, wo keine sein dürften, Zeichen, die es nicht geben sollte, und Datensätze aus einer Zeit vor der aktuellen Struktur.
Ein Umschaltfenster mit klarem Kriterium. Wann gilt die Umstellung als erfolgreich? Das gehört vorher festgelegt, nicht während der Umstellung diskutiert.
Ein erprobter Rückweg. Und zwar erprobt, nicht geplant. Ein Umzug ohne getesteten Rückweg ist kein Umzug, sondern ein Sprung. Die Frage, die dabei fast immer unterschätzt wird: Was passiert mit den Daten, die im neuen System entstanden sind, wenn man zurückrollt?
Das Vorhaben begründen
Modernisierung ohne äußeren Anlass wird selten bewilligt — das ist eine nüchterne Beobachtung, keine Klage. Die üblichen Anlässe: Ende der Herstellerunterstützung, Rechenzentrumsumzug, eine Sicherheitslücke, eine regulatorische Anforderung, ein ausgeschiedener Wissensträger.
Wenn der Anlass da ist, zählt dieselbe Argumentation wie bei technischen Schulden: Zahlen statt Adjektive. Betroffener Bereich, Änderungshäufigkeit, Mehraufwand gegenüber einem Referenzwert, Kosten des Nichtstuns.
Die Kosten des Nichtstuns sind dabei das stärkste Argument und werden am seltensten beziffert: das Risiko eines Ausfalls ohne verfügbaren Ersatz, die Schwierigkeit, Fachkräfte für eine abgekündigte Technologie zu finden, die Verzögerung jeder neuen Anforderung.
Und die KI?
Was Sprachmodelle beim Umgang mit Altsystemen tatsächlich leisten — und wo sie gefährlich sind.
Wo sie helfen:
- Code zusammenfassen. Eine dreitausend Zeilen lange Prozedur in fünf Sätzen — das spart beim ersten Verstehen echte Zeit.
- Abhängigkeiten aufzeigen. Was ruft was, wo wird dieser Wert gesetzt.
- Testfälle vorschlagen. Für Charakterisierungstests sind Modelle brauchbar, weil sie Randfälle im Code erkennen.
- Alte Sprachen erschließen. Bei Technologien, für die kaum noch jemand verfügbar ist, ist ein Modell oft der schnellste Zugang.
Wo sie gefährlich sind:
Bei undokumentierten Sonderfällen erfindet ein Modell Semantik. Es sieht eine Bedingung, die auf kundengruppe == "B7" prüft, und schreibt dazu eine plausible Begründung — die falsch sein kann, weil der wahre Grund eine Absprache von 2009 war, die nirgends steht. Diese Erklärungen klingen überzeugend, und genau das macht sie riskant.
Die Regel daraus: Modelle für „was tut der Code", Menschen für „warum tut er das". Das Erste ist im Code sichtbar und lässt sich prüfen. Das Zweite steht nirgends — und was nirgends steht, kann nur erfunden werden.
Mehr dazu, was Assistenten an der Arbeit ändern, in KI-Coding-Assistenten im Vergleich.
Häufige Fragen
Was ist Software-Migration? Der Umzug eines Systems in eine andere Umgebung, ohne die Fachlichkeit zu ändern. Abzugrenzen von Modernisierung (Umbau) und Ersatz (Neubau).
Welche Arten von Migration gibt es? Erneut hosten, anpassen, überarbeiten, neu bauen, durch Standardsoftware ersetzen, bewusst behalten oder ausmustern. Die letzten beiden werden am häufigsten übersehen.
Wann modernisiert man, wann ersetzt man? Modernisieren, wenn viel undokumentiertes Fachwissen im System steckt und die Fachlichkeit stabil ist. Ersetzen nur bei abgekündigter Technologiebasis und tragbarem Parallelbetrieb.
Wie geht man vor, ohne das System anzuhalten? Nach dem Strangler-Muster: Fassade davorstellen, Funktion für Funktion herauslösen und umleiten, Daten synchron halten, alte Implementierung abschalten.
Was ist ein Charakterisierungstest? Ein Test, der das tatsächliche Verhalten festschreibt statt des gewünschten — auch fehlerhaftes. Er ist das Sicherheitsnetz für Systeme ohne Testabdeckung.
Was kostet der Parallelbetrieb? Doppelte fachliche Pflege, doppelte Datenhaltung mit Abgleich, die Fassade als eigene Komponente — und Durchhaltevermögen, weil unterbrochene Ablösungen den schlechtesten aller Zustände hinterlassen.
Zusammenfassung und praktische Tipps
Ein laufendes System umzubauen ist Handwerk mit klaren Regeln. Die wichtigsten Punkte:
- Legacy heißt Änderungsangst, nicht Alter. Das Kriterium bestimmt die Maßnahme.
- Umzug und Umbau nicht im selben Schritt. Sonst weiß man bei einem Fehler nicht, woher er kommt.
- Der Neubau dauert länger und liefert weniger — die undokumentierten Sonderfälle sind die eigentliche Spezifikation.
- Strangler ist das risikoärmste Verfahren, aber nicht das billigste: doppelte Pflege, doppelte Daten, und es braucht Ausdauer.
- Fang beim Bereich mit hoher Änderungslast und klarer Grenze an.
- Charakterisierungstests schreiben auch falsches Verhalten fest — das ist richtig so.
- Ein Umzug ohne erprobten Rückweg ist ein Sprung.
- KI beantwortet „was", nicht „warum". Bei undokumentierten Sonderfällen erfindet sie Begründungen.
Mein Rat für den Einstieg: Bevor du über Zielarchitekturen sprichst, nimm dir einen Tag und schreib die Charakterisierungstests für den Bereich, den du zuerst anfassen willst. Danach weißt du zweierlei — wie das System sich tatsächlich verhält, und wie gut ihr es versteht. Beides brauchst du für jede weitere Entscheidung, und beides bekommst du auf keinem anderen Weg so schnell.
Ressourcen
- StranglerFigApplication – Martin Fowlers Beschreibung des Musters
- Working Effectively with Legacy Code – Michael Feathers, das Standardwerk zu Charakterisierungstests
- Branch by Abstraction – ergänzendes Verfahren für schrittweise Umbauten