Skip to content

AI Refactoring Guide für Entwickler

AI Refactoring Guide für Entwickler: Legacy Code modernisieren mit Claude & ChatGPT. 12 Refactoring-Patterns mit Prompts, vorher/nachher Beispielen und Best Practices.

Einleitung

Legacy Code anfassen ist wie eine Operation am offenen Herzen. KI-Tools machen diesen Prozess deutlich sicherer: Du kannst Code analysieren lassen, Refactoring-Pläne erstellen und den gesamten Umbau Schritt für Schritt durchführen – mit einem Sicherheitsnetz aus generierten Tests.

In diesem Guide zeige ich dir 12 Refactoring-Patterns, die du mit Claude und ChatGPT sofort anwenden kannst.


Grundsätzlich empfiehlt es sich, schrittweise vorzugehen.

Inhaltsverzeichnis

  1. Warum AI-gestütztes Refactoring?
  2. Vorbereitung: Safety Net aufbauen
  3. Pattern 1: Extract Method / Function
  4. Pattern 2: God Class auflösen
  5. Pattern 3: Callback Hell → Async/Await
  6. Pattern 4: Magic Numbers eliminieren
  7. Pattern 5: Conditional Logic vereinfachen
  8. Pattern 6: Dependency Injection einführen
  9. Pattern 7: Error Handling standardisieren
  10. Pattern 8: JavaScript → TypeScript Migration
  11. Pattern 9: Datenbankabfragen optimieren
  12. Pattern 10: API-Response-Format modernisieren
  13. Pattern 11: Konfiguration externalisieren
  14. Pattern 12: Monolith → Modularer Monolith
  15. Der komplette Refactoring-Workflow
  16. FAQ

Ebenfalls empfehlenswert ist eine regelmäßige Überprüfung der Ergebnisse.

Warum AI-gestütztes Refactoring?

Zusammenfassend lässt sich sagen, dass dies ein zentraler Aspekt ist.

  • Analyse: KI erkennt Code Smells und Anti-Patterns sofort
  • Plan: Außerdem erstellt schrittweise Refactoring-Pläne mit Reihenfolge
  • Tests: Ebenfalls generiert Tests vor dem Refactoring als Sicherheitsnetz
  • Transformation: Führt mechanische Code-Transformationen zuverlässig durch
  • Review: Prüft den refactored Code auf Korrektheit

Somit ergibt sich ein klarer Vorteil gegenüber manuellen Methoden.

Vorbereitung: Safety Net aufbauen

Grundsätzlich gibt es dabei einige Punkte zu beachten.

Regel Nr. 1: Kein Refactoring ohne Tests. Nutze diesen Prompt, bevor du anfängst:

Analysiere diesen Code und erstelle eine vollständige Test-Suite als Sicherheitsnetz für ein geplantes Refactoring:

```[sprache]
[Code einfügen]
```

Die Tests müssen:
1. Jedes aktuelle Verhalten (auch unerwünschtes) dokumentieren
2. Alle öffentlichen Methoden/Funktionen abdecken
3. Edge Cases und Grenzwerte testen
4. Als "Characterization Tests" dienen – sie beschreiben IST-Verhalten, nicht SOLL-Verhalten
5. Nach dem Refactoring weiterhin bestehen

Nutze [Jest/Vitest/pytest/etc.] als Test-Framework.

Darüber hinaus lässt sich das Beispiel leicht erweitern.


Im Folgenden gehe ich auf die wichtigsten Details ein.

Pattern 1: Extract Method / Function

Im Folgenden findest du alle wichtigen Details dazu.

Code Smell: Methode ist länger als 20 Zeilen oder macht mehr als eine Sache.

Refactore diese Funktion mit dem "Extract Method" Pattern:

```[sprache]
[Lange Funktion einfügen]
```

Regeln:
1. Jede extrahierte Funktion macht genau EINE Sache
2. Funktionsnamen beschreiben WAS getan wird (nicht WIE)
3. Maximale Funktionslänge: 15 Zeilen
4. Parameter minimieren (max. 3, sonst Options-Objekt)
5. Zeige vorher/nachher mit Erklärung jeder Extraktion

Ebenfalls sinnvoll ist es, verschiedene Varianten auszuprobieren.

Vorher

Dennoch solltest du einige Besonderheiten beachten.

function processOrder(order) {
  // 80 Zeilen mit Validierung, Berechnung, DB-Speicherung, E-Mail-Versand
}

Weiterhin ist es ratsam, die Ergebnisse immer kritisch zu prüfen.

Nachher

Dementsprechend solltest du die folgenden Aspekte kennen.

function processOrder(order) {
  validateOrder(order);
  const total = calculateTotal(order.items, order.discount);
  const savedOrder = await saveOrder({ ...order, total });
  await sendConfirmationEmail(savedOrder);
  return savedOrder;
}

Vor allem in der Praxis hat sich dieser Workflow bewährt.

Pattern 2: God Class auflösen

Weiterhin ist es wichtig, die Grundlagen zu verstehen.

Code Smell: Klasse mit mehr als 500 Zeilen oder mehr als 5 Verantwortlichkeiten.

Diese Klasse ist ein "God Object" mit zu vielen Verantwortlichkeiten:

```[sprache]
[Klasse einfügen]
```

Refactore sie nach dem Single Responsibility Principle:
1. Identifiziere alle unterschiedlichen Verantwortlichkeiten
2. Erstelle separate Klassen für jede Verantwortlichkeit
3. Nutze Dependency Injection für die Kommunikation
4. Erstelle eine Facade-Klasse für Rückwärtskompatibilität
5. Zeige die finale Ordnerstruktur

Somit sparst du Zeit und erhältst qualitativ hochwertigeren Output.


Ebenso hilfreich ist ein strukturierter Ansatz bei der Umsetzung.

Pattern 3: Callback Hell → Async/Await

Dabei spielen mehrere Faktoren eine wichtige Rolle.

Code Smell: Verschachtelte Callbacks, mehr als 3 Ebenen tief.

Konvertiere diesen Callback-basierten Code zu async/await:

```javascript
[Callback-Code]
```

Regeln:
1. Jeder Callback wird zu einem await
2. Error Handling mit try/catch statt Callback-Errors
3. Parallele Operationen mit Promise.all() wo möglich
4. Rückgabewerte statt Callback-Parameter
5. Behalte das exakt gleiche Verhalten bei

Tatsächlich lässt sich dieser Code direkt in dein Projekt übernehmen.


Tatsächlich zeigt die Praxis, dass dieser Ansatz sehr effektiv ist.

Pattern 4: Magic Numbers eliminieren

Insbesondere für den Einstieg sind die folgenden Informationen hilfreich.

Code Smell: Hardcoded Zahlen und Strings im Code ohne Erklärung.

Finde und ersetze alle Magic Numbers/Strings in diesem Code:

```[sprache]
[Code]
```

1. Identifiziere alle hardcoded Werte
2. Erstelle benannte Konstanten mit aussagekräftigen Namen
3. Gruppiere Konstanten logisch (als Enum, Objekt oder Modul)
4. Ersetze die Magic Numbers durch die Konstanten
5. Markiere Werte, die in eine Config-Datei gehören

Vor allem die detaillierten Anweisungen sorgen für präzisere Ergebnisse.


Außerdem profitierst du von einem systematischen Vorgehen.

Pattern 5: Conditional Logic vereinfachen

Tatsächlich ist dieser Bereich besonders wichtig für Entwickler.

Code Smell: Verschachtelte if/else-Ketten, komplexe Switch-Statements.

Vereinfache die Conditional Logic in diesem Code:

```[sprache]
[Code mit komplexen Conditions]
```

Nutze diese Techniken:
1. Early Returns (Guard Clauses) statt Verschachtelung
2. Strategy Pattern statt Switch
3. Lookup-Tabellen statt if/else-Ketten
4. Ternary nur für einfache Zuweisungen
5. Polymorphismus für typ-basierte Verzweigungen

Folglich verbessert sich die gesamte Codequalität deutlich.

Pattern 6: Dependency Injection einführen

Allerdings gibt es einige wichtige Unterschiede zu beachten.

Code Smell: Klassen, die ihre Dependencies selbst instanziieren (hard coupling).

Refactore diesen Code, um Dependency Injection zu nutzen:

```[sprache]
[Code mit hard-coded Dependencies]
```

1. Identifiziere alle externen Dependencies (DB, APIs, Services)
2. Erstelle Interfaces/Types für jede Dependency
3. Injiziere Dependencies über den Constructor
4. Erstelle eine Factory oder Composition Root
5. Zeige, wie die Klasse jetzt testbar ist (mit Mock-Beispiel)

Deshalb empfiehlt es sich, den Prompt schrittweise zu verfeinern.


Insbesondere für fortgeschrittene Projekte ist das relevant.

Pattern 7: Error Handling standardisieren

Im Grunde vereinfacht dieser Ansatz den gesamten Workflow erheblich.

Code Smell: Inkonsistentes Error Handling – manche Funktionen werfen, andere geben null zurück, wieder andere loggen nur.

Standardisiere das Error Handling in diesem Code:

```[sprache]
[Code mit inkonsistentem Error Handling]
```

Implementiere eine einheitliche Strategie:
1. Custom Error-Klassen mit Error-Codes
2. Einheitliche Error-Response-Struktur
3. Zentrale Error-Handler/Middleware
4. Logging-Strategie (was wird wo geloggt)
5. Error-Propagation-Regeln (wer fängt was)

Grundsätzlich kannst du diesen Prompt an deine Bedürfnisse anpassen.


Dementsprechend solltest du die einzelnen Schritte sorgfältig abarbeiten.

Pattern 8: JavaScript → TypeScript Migration

Somit kannst du direkt mit der Umsetzung beginnen.

Eines der häufigsten Refactoring-Projekte 2025/2026.

Migriere diese JavaScript-Datei zu TypeScript:

```javascript
[JS-Code]
```

Regeln:
1. Strikte Typen – kein 'any' außer es ist wirklich unvermeidbar
2. Interfaces für alle Objekt-Shapes
3. Generics wo sinnvoll
4. Utility-Types nutzen (Partial, Pick, Omit, Record)
5. Enums für feste Wertesets
6. Return-Types explizit angeben
7. Nullable Types mit strictNullChecks
8. Alle Typ-Definitionen in separate .d.ts oder type-Dateien

Folglich erhältst du mit diesem Ansatz deutlich bessere Resultate.


Hierbei hilft es, von konkreten Beispielen auszugehen.

Pattern 9: Datenbankabfragen optimieren

Außerdem gibt es hilfreiche Tools, die dich dabei unterstützen.

Optimiere diese Datenbankabfragen:

```[sprache]
[Code mit DB-Queries]
```

Prüfe auf:
1. N+1-Query-Problem → Eager Loading statt Lazy Loading
2. SELECT * → Nur benötigte Spalten
3. Fehlende Indizes (basierend auf WHERE/JOIN/ORDER BY Spalten)
4. Unnötige Subqueries → JOINs
5. Batch-Operationen statt Einzelabfragen in Schleifen
6. Connection Pooling und Caching-Möglichkeiten

Allerdings gibt es dabei einige Punkte, die du beachten solltest.

Pattern 10: API-Response-Format modernisieren

Vor allem für den praktischen Einsatz sind diese Informationen wertvoll.

Modernisiere das API-Response-Format dieser Endpunkte:

```[sprache]
[Controller/Route-Code]
```

Implementiere:
1. Einheitliches Response-Envelope: { data, meta, errors }
2. Pagination mit cursor-based oder offset Format
3. HTTP-Status-Codes korrekt nutzen (nicht alles 200)
4. Error-Responses mit { code, message, details }
5. HATEOAS-Links wo sinnvoll
6. Versionierung der API-Responses

Natürlich solltest du den generierten Code vor dem Einsatz testen.


Im Grunde sparst du dadurch langfristig viel Zeit.

Pattern 11: Konfiguration externalisieren

Deshalb lohnt es sich, dieses Thema genauer zu betrachten.

Extrahiere die hartcodierten Konfigurationswerte aus diesem Code:

```[sprache]
[Code mit hartcodierten Werten]
```

Erstelle:
1. Eine zentrale Config-Klasse/Modul
2. Environment-spezifische Werte via .env
3. Type-safe Config-Access
4. Validierung beim App-Start (alle Required-Werte vorhanden?)
5. Defaults für optionale Werte
6. Dokumentation aller Config-Optionen

Insbesondere die Struktur des Prompts ist dabei entscheidend für gute Ergebnisse.


Dabei ist der folgende Punkt besonders wichtig.

Pattern 12: Monolith → Modularer Monolith

Natürlich gibt es dabei verschiedene Herangehensweisen.

Analysiere diesen Monolith-Code und erstelle einen Plan für einen Modularen Monolith:

```[sprache]
[Code / Ordnerstruktur einfügen]
```

1. Identifiziere Bounded Contexts (fachliche Domänen)
2. Erstelle eine Modul-Karte mit klaren Grenzen
3. Definiere öffentliche APIs zwischen Modulen
4. Erstelle einen schrittweisen Migrationsplan
5. Zeige die Ziel-Ordnerstruktur
6. Identifiziere geteilte Entitäten und wie man sie entkoppelt

Dementsprechend ist eine manuelle Überprüfung empfehlenswert.


Deshalb ist es wichtig, diesen Abschnitt aufmerksam zu lesen.

Der komplette Refactoring-Workflow

Folglich profitierst du von einem besseren Verständnis dieser Konzepte.

So sieht ein AI-gestützter Refactoring-Prozess in der Praxis aus:

  1. Analyse: KI analysiert den Code und listet Code Smells auf
  2. Priorisierung: Sortiere nach Impact und Risiko
  3. Safety Net: Generiere Characterization Tests (vor dem Refactoring)
  4. Plan: Erstelle einen schrittweisen Plan (jeder Schritt ist ein Commit)
  5. Ausführung: Ein Pattern nach dem anderen – Tests nach jedem Schritt
  6. Review: KI reviewed den refactored Code
  7. Dokumentation: Schreibe auf, was geändert wurde und warum

Golden Rule: Nie mehr als ein Refactoring-Pattern pro Commit. Wenn etwas schiefgeht, kannst du einzelne Schritte revertieren.


Weiterhin ist es sinnvoll, die Ergebnisse regelmäßig zu überprüfen.

FAQ

Wie überzeuge ich meinen Chef, Zeit für Refactoring einzuplanen?

Ebenfalls relevant sind die praktischen Anwendungsbeispiele.

Nutze die KI, um eine Kosten-Nutzen-Analyse zu erstellen: „Analysiere diesen Code und schätze: Wie viel Zeit kostet die aktuelle technische Schuld pro Feature? Wie viel würde Refactoring sparen?“

Soll ich alles auf einmal oder schrittweise refactoren?

Ebenso wichtig ist es, die Best Practices zu kennen.

Immer schrittweise. Die Boy Scout Rule: „Leave the code better than you found it.“ Kleine, kontinuierliche Verbesserungen sind nachhaltiger als Big-Bang-Rewrites.

Wie gehe ich mit Code ohne Tests um?

Darüber hinaus bietet dieser Abschnitt konkrete Beispiele und Tipps.

Schritt 1: Characterization Tests generieren lassen (Prompt aus der Vorbereitung). Schritt 2: Dann erst refactoren. Die KI kann Tests auch für schwer testbaren Code erstellen.

Was ist der häufigste Refactoring-Fehler?

Dennoch solltest du einige Besonderheiten beachten.

Zu viel auf einmal ändern. Refactoring und Feature-Änderungen mischen ist ein Rezept für Disaster. Halte Refactoring-Commits und Feature-Commits strikt getrennt.


Dennoch sollte man die Limitierungen im Blick behalten.

Verwandte Artikel:


Zusammenfassend bietet dieser Abschnitt praktische Handlungsempfehlungen.

Zuletzt aktualisiert: März 2026