Anwendungs-Refactoring hat sich seit 2024 stärker verändert als viele Team-Routinen, weil KI-gestützte Codeproduktion, SBOM-Pflichten und schnellere Runtime-Wechsel die Engpässe verschoben haben. Meine Position: Ein Tech Lead in einer 15- bis 30-köpfigen Organisation sollte weniger über „sauberen Code“ sprechen und härter messen, welche Änderungskosten wirklich sinken.
Refactoring ohne Änderungsdaten ist seit 2024 meistens Selbstbeschäftigung
Der alte Rat, zuerst die hässlichsten Klassen aufzuräumen, ist überholt, weil Hässlichkeit selten der Engpass ist, wenn Builds, Reviews und Abhängigkeiten die Durchlaufzeit bestimmen. Ich halte den Ansatz Anwendungs-Refactoring: Code sauber und wartbar machen für zu breit, weil Wartbarkeit ohne Change-Daten schnell zur Geschmacksfrage wird.
Für eine Engineering-Organisation mit 15 bis 30 Personen ist die knappe Ressource nicht Refactoring-Ideen, sondern koordinierte Aufmerksamkeit. Wenn fünf Entwickler gleichzeitig an derselben Kernbibliothek „aufräumen“, steigt die Merge-Reibung, weil sich semantisch harmlose Diffs gegenseitig blockieren. Deshalb sollte Refactoring seit 2024 am Änderungsfluss hängen: Welche Dateien ändern sich oft, verursachen Defekte oder verzögern Releases?
Ich würde keinen sechswöchigen Refactoring-Sprint ausrufen, weil er Produktarbeit künstlich stoppt und nach zwei Wochen politische Verteidigung statt technischer Klarheit erzeugt. Besser ist ein Budget, das Sie nachjustieren: 10 Prozent der Sprint-Kapazität für strukturelle Änderungen ist ein brauchbarer Startwert zum Kalibrieren, weil er sichtbar genug ist, ohne Feature-Teams aus dem Takt zu bringen.
Die Metriken haben sich ebenfalls verschoben. DORA-Metriken wie Lead Time for Changes und Change Failure Rate sind für Refactoring wertvoller als globale Code-Coverage, weil sie den Fluss zur Produktion sichtbar machen. Als selbst zu messender Teamwert ist eine p75-Lead-Time von 2 Arbeitstagen ein guter Warnpunkt, weil längere Durchlaufzeiten in kleinen Organisationen meistens auf Review-Stau, fragile Tests oder zu große Pull Requests hindeuten.
SonarQube 10.6, CodeClimate Velocity, GitHub Insights und Linear-Zykluszeiten liefern keine Wahrheit, aber sie geben brauchbare Reibungsdaten, weil sie Änderungshäufigkeit, Review-Dauer und Defektcluster verbinden. Eine Regel ist dabei unbequem: Eine Datei, die selten geändert wird, bekommt nur dann Refactoring-Budget, wenn sie ein Sicherheits-, Betriebs- oder Upgrade-Risiko blockiert.
KI hat Code billiger gemacht, aber Reviews teurer
Seit GitHub Copilot, JetBrains AI Assistant und Cursor in vielen Teams normal geworden sind, ist die Menge an plausibel aussehendem Code gestiegen, weil Entwickler schneller Varianten erzeugen können. Der Rat „extrahiere Methoden, bis es lesbar wirkt“ ist dadurch schwächer geworden, weil mehr kleine Abstraktionen die Review-Fläche vergrößern und semantische Fehler hinter sauberen Namen verstecken können.
Das heißt nicht, dass KI-generierter Code schlecht ist, denn LLMs sind bei mechanischen Umformungen oft zuverlässig, wenn Tests und statische Regeln die Grenzen setzen. Es heißt aber, dass ein Tech Lead Refactoring nicht mehr als Handwerksromantik organisieren sollte. Jede größere Umformung braucht eine Prüfkette aus Tests, statischer Analyse und Laufzeitdaten, weil menschliche Reviews in kleinen Teams nicht jede semantische Verschiebung erkennen.
Der Beitrag Anwendungs Refactoring Best Practices fuer sauberen Code bleibt als Checkliste nützlich, aber ich würde seine Priorität heute umdrehen, weil die wichtigste Frage nicht mehr „Ist der Code elegant?“, sondern „Ist die Änderung maschinell beweisbar und betrieblich ungefährlich?“ lautet.
Konkreter: JaCoCo 0.8.12, Vitest 2.x, pytest 8.x und Playwright 1.45 können Refactoring absichern, wenn sie die relevanten Pfade treffen. Eine globale Coverage-Zahl bleibt jedoch gefährlich, weil 80 Prozent Gesamtdeckung tote Beruhigung erzeugen können. Als zu justierender Grenzwert ist 65 Prozent Coverage auf geändertem Code vernünftiger, weil er lokale Verantwortung erzwingt und neue Risiken nicht hinter alter Testmasse versteckt.
Bei Reviews würde ich eine harte Obergrenze setzen: 400 geänderte Zeilen pro Pull Request sind ein anpassbarer Richtwert, weil darüber Review-Qualität in kleinen Teams häufig sinkt. Diese Zahl ist keine Naturkonstante, aber sie zwingt Refactoring in kleine, rückrollbare Scheiben. Wenn eine Umstellung größer sein muss, sollte sie mechanisch generiert, separat reviewed und mit einer Architekturregel abgesichert werden.
Mechanische Migration schlägt manuelle Schönheit, wenn die Plattform sich bewegt
Der größte Wandel der letzten zwei Jahre liegt in Plattform-Baselines. JDK 21 ist als LTS-Version etabliert, .NET 8 ist LTS, Node.js 20 wurde für viele Produktionssysteme zum Standard, und Spring Boot 3.x verlangt laut Herstellerdokumentation mindestens Java 17, weil der Wechsel auf Jakarta EE 9 die Paketnamen von javax.* zu jakarta.* verschoben hat. Diese Zahlen sind vendor-publiziert, nicht Meinungswerte.
Dadurch ist Refactoring heute oft eine Upgrade-Disziplin. Wer noch manuell Imports ersetzt, Properties umbenennt oder triviale API-Wechsel per IDE erledigt, verschwendet Zeit, weil OpenRewrite, Renovate, Dependabot, Error Prone, ESLint 9 mit flat config und TypeScript 5.5 solche Änderungen reproduzierbarer machen. Manuelle Nacharbeit bleibt nötig, aber sie sollte auf fachliche Semantik beschränkt sein.
#!/usr/bin/env bash set -euo pipefail mvn -q -DskipTests org.openrewrite.maven:rewrite-maven-plugin:5.40.0:dryRun \ -Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_2 semgrep ci --config p/owasp-top-ten --baseline-ref origin/main npm audit --audit-level=high pytest -q --maxfail=1
Diese Art Pipeline ist nicht perfekt, weil jedes Werkzeug blinde Flecken hat, aber sie macht Refactoring wiederholbar. OpenRewrite 5.40.0 kann Java- und Spring-Migrationen typbewusst durchführen, weil es AST und Build-Kontext nutzt. Semgrep 1.75 mit –baseline-ref eignet sich für Sicherheits- und Idiomregeln, weil es schnell über mehrere Sprachen läuft und neue Treffer von altem Rauschen trennt.
Der explizite Vergleich ist simpel: OpenRewrite gewinnt bei typgebundenen Java-Migrationen wie Spring Boot 2.7 auf 3.2, weil Rezepte Imports, Dependencies und APIs konsistent ändern; der Preis sind Rezeptpflege, Build-Zeit und ein engerer Technologie-Fokus. Semgrep Autofix gewinnt bei sprachübergreifenden Pattern-Änderungen wie unsicheren Crypto-Aufrufen oder verbotenen Logging-Feldern, weil Regeln schnell geschrieben sind; der Preis sind False Positives und weniger semantische Tiefe.
Für JavaScript- und TypeScript-Stacks gilt dasselbe Muster. jscodeshift, ts-morph und ESLint 9-Regeln schlagen manuelle Rename-Partys, weil sie dieselbe Änderung hundertfach gleich ausführen. Für C#-Teams sind Roslyn Analyzers und dotnet format sinnvoller als Stil-Debatten, weil sie Review-Zeit sparen und Verstöße früh im Build stoppen.
Sauberer Code ist weniger wert als überprüfbare Grenzen
Viele ältere Refactoring-Ratschläge überschätzen interne Schönheit, weil sie unterschätzen, wie schnell Abhängigkeiten, Lieferketten und Observability-Erwartungen gewachsen sind. Seit 2024 fragen mehr Kunden, Plattformteams und Security-Verantwortliche nach SBOMs, Signaturen und nachvollziehbaren Artefakten. CycloneDX 1.6, SPDX 2.3, SLSA v1.0 und Sigstore Cosign sind keine Dekoration, weil sie zeigen, welche Komponenten gebaut, geprüft und ausgeliefert wurden.
Das macht manche Empfehlungen alt. „Erst Architektur aufräumen, dann Security nachziehen“ ist falsch, weil veraltete Dependencies und unklare Artefakte während des Refactorings neue Risiken erzeugen. Renovate 37 mit gruppierten Minor-Updates und Dependabot Security Updates sind pragmatischer, weil sie die Abhängigkeitslast kontinuierlich sichtbar machen. Eine wöchentliche Dependency-Update-Welle ist ein zu steuernder Rhythmus, weil tägliche Update-PRs kleine Teams nervös machen und monatliche Bündel zu groß werden.
Auch Observability ist kein nachträglicher Luxus mehr. OpenTelemetry 1.30, Prometheus, Grafana, Datadog APM oder Elastic APM sollten vor riskanten Refactorings die relevanten Pfade messen, weil sonst niemand erkennt, ob ein „sauberer“ Umbau Latenz, Fehlerraten oder Queue-Tiefen verschlechtert. Eine p95-Latenz von 300 Millisekunden ist als lokal festzulegender Grenzwert brauchbar, weil Nutzerwirkung und Systemtyp stark variieren.
Architektonische Grenzen sollten Sie klein und überprüfbar halten. ArchUnit 1.3 kann in Java verhindern, dass UI-Code direkt auf Persistenzklassen zugreift, weil Regeln als Tests im Build laufen. Pact 4 hilft bei Consumer-Driven Contracts, weil es API-Erwartungen versioniert statt sie in Slack-Absprachen zu verstecken. Testcontainers 1.20 ist bei Datenbank- und Broker-Integrationen nützlich, weil Tests näher an echten Abhängigkeiten laufen als bei reinem Mocking.
Ich würde dagegen keine pauschale „alles muss hexagonal werden“-Vorgabe machen, weil sie viele Teams zu leeren Ports, Adaptern und DTO-Schichten verleitet. Hexagonal Architecture lohnt sich, wenn fachliche Regeln lange leben und Infrastruktur häufig wechselt; ein schlichtes Modul mit klaren Paketgrenzen gewinnt, wenn die Anwendung klein ist und die Hauptkosten in Lieferfähigkeit, nicht in Austauschbarkeit liegen.
Eine unbequeme Regel für Tech Leads: Entfernen Sie Abstraktionen, die nur für theoretische Zukunft gebaut wurden, weil sie jeden Review verlängern und neue Mitarbeitende in falsche Alternativen führen. Refactoring heißt 2026 häufiger Löschen als Verschönern. Wenn ein Interface genau eine Implementierung hat und keine Test- oder Plugin-Grenze bildet, sollte es zur Disposition stehen, weil es wahrscheinlich Koordination ohne Nutzen erzeugt.
Der erste Schritt ist ein Refactoring-Register mit Ablaufdatum
Beginnen Sie nicht mit einer großen Zielarchitektur, sondern mit einem Refactoring-Register für die nächsten 30 Tage, weil kurze Fristen politische Debatten reduzieren. Tragen Sie fünf Kandidaten ein: Datei oder Modul, beobachteter Schmerz, Messwert, Sicherheitsbezug, geplanter Rückbau. Streichen Sie alles ohne klare Metrik. Danach automatisieren Sie die erste mechanische Änderung und messen, ob die nächste Änderung wirklich schneller wird.



