Erstgespräch vereinbaren
Kommende Termine
4. Mai 2026
IT-Talk: Digitale Verantwortung
Details →
12. Juni 2026
Vernissage
28. September 2026
IT-Talk: Event-Driven Architecture

Legacy Code - Wie funktioniert das System?

Strategien zum Verstehen und Verbessern von Legacy Code: Tests schreiben, Code analysieren und schrittweise refaktorisieren.

Digitaler Code-Strom

Softwareprojekte beginnen typischerweise als Greenfield-Entwicklung, akkumulieren aber mit der Zeit Komplexität. Wenn Änderungen an stabilen Systemen notwendig werden, fehlen Entwicklern oft Dokumentation und das Wissen des ursprünglichen Teams.

Das Kennenlernen

Empfehlungen zum Verständnis unbekannter Systeme:

  • Kollegen nach Systemwissen befragen
  • Eingesetzte Technologien identifizieren
  • Interne Dokumentationssysteme durchsuchen (Wikis, Tickets, Blogs)
  • Bestehenden Code und Tests untersuchen

Kontaktaufnahme

Es empfiehlt sich, das System lokal zum Laufen zu bringen und zu versuchen, die zu ändernden Features zu nutzen. Services sollten auch ohne traditionelle UI-Oberflächen angestoßen werden.

Wenn der Patient unkooperativ ist…

Es gibt Szenarien mit minimaler Dokumentation, fehlenden Tests oder irreführenden Testfällen.

Die ersten gemeinsamen Schritte

Tests schreiben

Durch das Schreiben von Tests zu bestehenden Funktionen kann man Annahmen verifizieren und das Systemverhalten dokumentieren.

Code kaputt machen

Absichtlich Fehler einbauen, um den Code-Fluss zu verstehen und zu identifizieren, welche Methoden aufgerufen werden.

Informationsextraktion

Metadaten aus Konfigurationsdateien extrahieren und Abhängigkeiten mit Tools wie Graphviz visualisieren.

Verbesserung des bestehenden Codes

Annotationen

Annotationen als zur Laufzeit unsichtbare Metadaten mit IDE-Support-Vorteilen gegenüber Kommentaren nutzen.

Interfaces

Interfaces verwenden, um Klassen zu markieren und “Gottklassen” durch Aufteilen großer Interfaces in kleinere, fokussiertere Verträge zu adressieren.

Beispiel-Refactoring:

public interface ReadOnlyIterator<E> {
    boolean hasNext();
    E next();
}

public interface MutableIterator<E> extends ReadOnlyIterator<E> {
    void remove();
}

Klassen statt Strings

Dedizierte Typen erstellen statt primitive Strings für Parameter zu verwenden. Ein detailliertes Beispiel mit einer EMail-Klasse und Refactoring-Schritten zeigt den Vorteil dieses Ansatzes.

Neuimplementierungen

Vor einer vollständigen Code-Ersetzung empfiehlt sich umfassendes Testen. Parameterkombinationen sollten gründlich getestet werden.

Fazit

Kreative Ansätze beim Testen sind gefragt. “Unsaubere” Test-Implementierungen sind vorübergehend akzeptabel als sicherere Alternative zur Änderung von nicht testbarem Code ohne Verifikationsmechanismen.

Zurück zum Blog