Refactoring von Legacy-Code in Java: Schritt-für-Schritt-Anleitung von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Was ist Legacy-Code und warum muss man ihn refactoren

\n\n

Jeder Java-Entwickler stößt früher oder später auf Legacy-Code – veraltete, schlecht strukturierte und kaum dokumentierte Software. Solcher Code ist oft ohne Unit-Tests geschrieben, verletzt die SOLID-Prinzipien, und seine Wartung wird zum Albtraum. Das Refactoring von Legacy-Code in Java ist keine bloße Laune, sondern eine Notwendigkeit, um technische Schulden zu reduzieren und die Entwicklung neuer Features zu beschleunigen.

\n\n

In diesem Artikel behandeln wir das Refactoring von Legacy-Code in Java von A bis Z: von der Identifizierung problematischer Stellen bis zur sicheren Implementierung von Änderungen mit modernen Werkzeugen.

\n\n

Phase 1: Analyse und Bewertung von Legacy-Code

\n\n

Bevor Sie den Code ändern, müssen Sie ihn verstehen. Hier sind die wichtigsten Analyseschritte:

\n\n

1.1. Metriken sammeln und "Code Smells" erkennen

\n\n

Verwenden Sie statische Analysatoren:

\n
    \n
  • SonarQube – erkennt Duplikate, komplexe Methoden, Verstöße gegen den Code-Stil
  • \n
  • PMD – findet potenzielle Fehler und toten Code
  • \n
  • Checkstyle – prüft die Einhaltung von Formatierungsstandards
  • \n
\n\n

Beispiel für einen typischen "Code Smell" – eine riesige Methode:

\n\n
public class OrderProcessor {\n    public void process(Order order) {\n        // 200 Zeilen Code: Validierung, Rabattberechnung, E-Mail-Versand, Logging...\n        // Teilen Sie dies in kleine Methoden auf!\n    }\n}
\n\n

1.2. Erstellung einer Abhängigkeitskarte

\n\n

Legacy-Code enthält oft zyklische Abhängigkeiten und God-Klassen. Verwenden Sie Visualisierungswerkzeuge:

\n
    \n
  • IntelliJ IDEA Dependency Viewer – integriertes Werkzeug
  • \n
  • Structure101 – professionelle Lösung für die Architekturanalyse
  • \n
\n\n

Phase 2: Erstellung eines Sicherheitsnetzes aus Tests

\n\n

Ohne Tests ist Refactoring russisches Roulette. Ihr Ziel ist es, die wichtigsten Szenarien mit Characterization Tests (Tests, die das aktuelle Verhalten festhalten) abzudecken.

\n\n

2.1. Die "Golden Master"-Technik

\n\n

Für große Codeblöcke ohne Tests:

\n
    \n
  1. Starten Sie das System mit echten Daten
  2. \n
  3. Speichern Sie die Ausgabe (Logs, API-Antworten) als Referenz
  4. \n
  5. Vergleichen Sie nach dem Refactoring das Ergebnis mit der Referenz
  6. \n
\n\n

2.2. Beispiel eines Tests für eine Legacy-Klasse

\n\n
import org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.*;\n\npublic class LegacyCalculatorTest {\n    \n    @Test\n    public void testLegacyCalculation() {\n        LegacyCalculator calc = new LegacyCalculator();\n        // Aktuelles Verhalten festhalten\n        int result = calc.calculate(10, 5);\n        assertEquals(15, result); // Wenn ein Fehler vorliegt, speichert der Test den Fehler!\n    }\n}
\n\n

Wichtig: Committen Sie zuerst die Tests, dann refactoren Sie. Ein grüner Test ist Ihre Versicherung.

\n\n

Phase 3: Schrittweises Refactoring mit Patterns

\n\n

Refactoring von Legacy-Code in Java bedeutet nicht "alles neu schreiben", sondern eine Reihe kleiner, sicherer Transformationen.

\n\n

3.1. Methode extrahieren (Extract Method)

\n\n

Das sicherste Refactoring. Die IDE macht dies automatisch.

\n\n

Vorher:

\n
public void printInvoice(Invoice invoice) {\n    double total = 0;\n    for (Item item : invoice.getItems()) {\n        total += item.getPrice() * item.getQuantity();\n    }\n    double discount = total > 100 ? total * 0.1 : 0;\n    double finalTotal = total - discount;\n    System.out.println("Total: " + finalTotal);\n}
\n\n

Nachher (mit extrahierten Methoden):

\n
public void printInvoice(Invoice invoice) {\n    double total = calculateTotal(invoice);\n    double discount = calculateDiscount(total);\n    double finalTotal = total - discount;\n    printTotal(finalTotal);\n}\n\nprivate double calculateTot                

Blogs

Buchempfehlungen