Logo von nextlevels
Projekt anfragen
Zurück zum Wiki

Refactoring

Zuletzt aktualisiert am

Refactoring bezeichnet die gezielte Veränderung der inneren Struktur von Software, ohne ihr von außen sichtbares Verhalten zu ändern. Der Code wird lesbarer, einfacher erweiterbar und günstiger zu warten, während Funktionen, Schnittstellen und Ergebnisse für Nutzer und angebundene Systeme exakt gleich bleiben. Geprägt hat den Begriff Martin Fowler mit seinem Buch „Refactoring: Improving the Design of Existing Code“, das 1999 erschien und 2018 in zweiter Auflage neu aufgelegt wurde.

Für Geschäftsführer und IT-Leiter ist Refactoring vor allem eine Investitionsentscheidung. Es kostet Entwicklerzeit, liefert aber kein neues Feature, das sich dem Vertrieb zeigen lässt. Dieser Eintrag erklärt, was Refactoring konkret umfasst, welche Voraussetzungen es braucht, wie es sich von Rewrite und Modernisierung unterscheidet, wann es ausreicht und wann nicht, und was es wirtschaftlich bringt.

Was Refactoring ist und was nicht

Die Definition hat zwei harte Kriterien. Erstens: Das Verhalten bleibt gleich. Ein Refactoring fügt keine Funktion hinzu, behebt keinen fachlichen Fehler und ändert keine Ausgabe. Zweitens: Die Struktur ändert sich. Namen werden präziser, Funktionen kleiner, Abhängigkeiten klarer, Duplikate verschwinden. Fowler beschreibt Refactoring deshalb als eine Abfolge vieler kleiner, verhaltenserhaltender Umbauten, von denen jeder einzelne für sich genommen fast trivial ist. Die Wirkung entsteht durch die Summe.

Diese enge Definition ist wichtig, weil der Begriff im Projektalltag gern als Sammelbezeichnung für „wir räumen mal auf“ verwendet wird. Wer beim Aufräumen gleichzeitig ein Feature einbaut und einen Bug fixt, macht kein Refactoring mehr, sondern drei Dinge auf einmal. Genau das macht Fehler schwer zu finden, wenn hinterher etwas nicht funktioniert. Die saubere Trennung ist keine Pedanterie, sondern Risikomanagement.

Ein verbreitetes Missverständnis betrifft auch den Zeitpunkt. Refactoring ist keine Sonderphase, die man alle zwei Jahre einplant, sondern Teil der normalen Entwicklungsarbeit. Fowler nennt das die „Zwei-Hüte-Regel“: Entweder du trägst gerade den Hut „Funktion hinzufügen“ oder den Hut „Struktur verbessern“, aber nie beide gleichzeitig. Zwischen den Hüten darf beliebig oft gewechselt werden, auch mehrfach pro Stunde.

Typische Refactorings

Fowlers Katalog, der auch online unter refactoring.com gepflegt wird, umfasst in der zweiten Auflage rund siebzig benannte Umbauten. Die wichtigsten lassen sich in wenigen Sätzen erklären. Extract Function löst einen Codeblock aus einer langen Funktion heraus und gibt ihm einen sprechenden Namen; die lange Funktion wird dadurch zu einer lesbaren Abfolge von Schritten. Rename ändert den Namen einer Variablen, Funktion oder Klasse, damit er ausdrückt, was das Ding tatsächlich tut. Das klingt banal, ist aber eines der wirkungsvollsten Refactorings überhaupt, weil Code weit häufiger gelesen als geschrieben wird. Move Function oder Move Field verschiebt Logik dorthin, wo die Daten liegen, mit denen sie arbeitet, und reduziert so Abhängigkeiten zwischen Modulen.

Über den klassischen Katalog hinaus zählen in der Praxis auch technische Pflegearbeiten dazu, die das Verhalten erhalten, aber die Basis modernisieren. Dependency-Upgrades heben Bibliotheken und Frameworks auf aktuelle Versionen, schließen Sicherheitslücken und halten den Zugang zu neuen Features offen. Bei mobilen Apps kommt die Hebung des Target-SDK hinzu: Google und Apple verlangen für Store-Einreichungen regelmäßig, dass Apps gegen eine aktuelle Android- beziehungsweise iOS-Version gebaut werden. Wer das versäumt, kann irgendwann keine Updates mehr veröffentlichen. Solche Arbeiten liefern dem Nutzer nichts Sichtbares, sind aber Voraussetzung dafür, dass die App im Store bleibt und das Team überhaupt noch sicher ändern kann.

Voraussetzungen: Tests, Versionskontrolle, kleine Schritte

Refactoring ohne Sicherheitsnetz ist Glücksspiel. Das wichtigste Netz sind automatisierte Tests. Sie beweisen nach jedem Umbau, dass das Verhalten unverändert ist. Fehlen sie, lässt sich die Grundbedingung „Verhalten bleibt gleich“ schlicht nicht prüfen, und jeder Umbau wird zur Mutprobe. Fowler ist hier eindeutig: Der erste Schritt in einem ungetesteten Altsystem ist nicht das Refactoring, sondern das Schreiben von Tests, die das aktuelle Verhalten festhalten, auch wenn dieses Verhalten Fehler enthält. Solche Charakterisierungstests sind nicht schön, aber sie machen jeden folgenden Schritt überprüfbar.

Die zweite Voraussetzung ist Versionskontrolle mit kleinen Commits. Ein Refactoring, das fünfzig Dateien in einem Rutsch ändert, ist im Review kaum zu beurteilen und im Fehlerfall nicht sauber rückgängig zu machen. Kleine, benannte Schritte wie „Rename OrderService.process zu OrderService.submit“ sind nachvollziehbar und lassen sich einzeln zurückdrehen. Die dritte Voraussetzung folgt daraus: Disziplin bei der Schrittgröße. Fowlers Mechanik besteht darin, nach jedem Mini-Umbau zu kompilieren und zu testen. Wer das durchhält, findet Fehler innerhalb von Minuten statt Tagen.

Dazu kommt Werkzeugunterstützung. Moderne IDEs führen Rename, Extract und Move automatisiert und über alle Verwendungsstellen hinweg aus, was die Fehlerquote drastisch senkt. Statische Analyse zeigt, wo Komplexität und Duplikate sitzen. Eine Continuous-Integration-Pipeline, die bei jedem Push die Tests laufen lässt, macht das Sicherheitsnetz für das ganze Team sichtbar, nicht nur für den Entwickler am Rechner.

Abgrenzung: Refactoring, Rewrite, Modernisierung

Die Begriffe werden in Angeboten und Entscheidungsvorlagen oft vermischt, beschreiben aber sehr unterschiedliche Vorhaben mit unterschiedlichem Risiko. Refactoring arbeitet im bestehenden Code und erhält das Verhalten. Ein Rewrite baut das System von Grund auf neu, meist mit anderer Technologie, und ersetzt das alte am Ende komplett. Modernisierung ist der Oberbegriff für alle Maßnahmen, die ein Altsystem zukunftsfähig machen; sie kann Refactoring enthalten, aber auch Migrationen, Container-Betrieb oder das Herauslösen einzelner Dienste. Replatforming wiederum wechselt die Plattform unter dem System, etwa von einem Shopsystem auf ein anderes, und ist damit näher am Rewrite als am Refactoring.

Refactoring, Rewrite und Modernisierung im Vergleich
KriteriumRefactoringRewriteModernisierung
Verhalten nach außenBleibt identischWird neu definiert, oft mit AbweichungenBleibt meist gleich, kann erweitert werden
CodebasisBestehender Code wird umgebautNeuer Code ersetzt den altenMischung: Teile bleiben, Teile werden ersetzt
Typische DauerStunden bis Wochen, laufendMonate bis JahreQuartale, in Etappen
RisikoGering, wenn Tests vorhanden sindHoch: Parallelbetrieb, Feature-Lücken, BudgetMittel, abhängig von Schnittgröße
Nutzen für den FachbereichIndirekt: schnellere ÄnderungenDirekt sichtbar, aber spätSchrittweise sichtbar
Typischer AuslöserJede Änderung, Code SmellsTechnologie am Ende, Team ohne Know-howBetriebskosten, Sicherheit, Compliance

Der entscheidende Unterschied liegt im Risiko. Ein Rewrite verspricht ein sauberes System, verlangt aber monatelang Parallelbetrieb, in dem das alte System gewartet und das neue gebaut wird. Joel Spolsky hat das schon vor Jahren als den größten strategischen Fehler eines Softwareunternehmens bezeichnet, weil das Altsystem Wissen enthält, das niemand mehr kennt: Sonderfälle, Workarounds, Kundenabsprachen. Refactoring konserviert dieses Wissen, weil der Code nie weggeworfen wird. Die Konsequenz für die Praxis: Die meisten Systeme, für die ein Rewrite gefordert wird, bräuchten erst einmal Tests und einige Wochen konsequentes Refactoring. Erst wenn das nicht hilft, ist der Neubau eine ehrliche Option.

Wann Refactoring reicht und wann nicht

Refactoring reicht, solange drei Bedingungen erfüllt sind. Das Framework oder die Plattform wird weiter gepflegt, erhält Sicherheitsupdates und hat einen Weg in die nächste Hauptversion. Das Team kennt den Code oder kann ihn mit vertretbarem Aufwand kennenlernen, und es fühlt sich sicher genug, Änderungen zu machen. Und die Grundarchitektur passt zu den fachlichen Anforderungen der nächsten Jahre; sie ist vielleicht unordentlich, aber nicht falsch.

Kippt eine dieser Bedingungen, stößt Refactoring an Grenzen. Ein abgekündigtes Framework lässt sich nicht durch sauberere Funktionsnamen retten; hier ist eine Migration fällig, die zwar refactoring-artig in kleinen Schritten laufen kann, aber eine andere Zielsetzung hat. Fehlt dem Team jede Sicherheit, weil der ursprüngliche Entwickler weg ist und kein Test existiert, muss erst die Testbasis entstehen, bevor irgendein Umbau vertretbar ist. Und wenn die Architektur grundsätzlich nicht trägt, etwa ein Monolith, der auf Mandantenfähigkeit oder zehnfache Last skalieren soll, dann hilft lokales Umbauen wenig. Dann geht es um Zerlegung, zum Beispiel das schrittweise Herauslösen von Diensten, oder um einen gezielten Teil-Rewrite.

Ein nützlicher Test für die Entscheidung ist die Frage nach der technischen Schuld: Ist sie lokal oder strukturell? Lokale Schuld sitzt in einzelnen Modulen, die zu groß, zu verschachtelt oder schlecht benannt sind. Sie ist mit Refactoring abtragbar. Strukturelle Schuld sitzt in Entscheidungen, die das ganze System durchziehen, etwa ein Datenmodell, das die Fachlichkeit falsch abbildet, oder eine Abhängigkeit, von der sich nichts trennen lässt. Sie verlangt mehr als Refactoring. Bei Individualsoftware ist diese Unterscheidung besonders relevant, weil dort niemand außer dem eigenen Team oder dem Dienstleister die Entscheidung treffen kann.

Kosten und Nutzen

Die Kosten von unterlassenem Refactoring lassen sich beziffern. In einer Entwicklerumfrage, die SonarSource unter dem Titel „Developers spend 30% of their time on code maintenance“ veröffentlicht hat, gaben professionelle Entwickler an, im Schnitt rund 30 Prozent ihrer Arbeitswoche mit Codewartung zu verbringen, also etwa 12 Stunden pro Woche. Die Spanne reichte von 11 bis 50 Prozent; größere Teams lagen über dem Durchschnitt, vermutlich weil sie mit älteren und größeren Codebasen arbeiten. Rund ein Viertel der Wartungszeit entfiel auf Open-Source-Abhängigkeiten, und die zeitaufwendigste Einzelaufgabe war der Wechsel auf eine neue Hauptversion eines Frameworks oder einer Bibliothek. Die Umfrage zitiert zudem einen Stripe-Report, der sogar 17,3 Stunden pro Woche für Wartung und schlechten Code ansetzt.

Für ein Team von fünf Entwicklern bedeuten 30 Prozent Wartungsanteil rechnerisch anderthalb Vollzeitstellen, die nicht an neuen Funktionen arbeiten. Jeder Prozentpunkt, den Refactoring aus diesem Block herausholt, ist entweder gewonnene Feature-Kapazität oder eingesparte Personalkosten. Der Nutzen zeigt sich allerdings nicht in der Woche des Umbaus, sondern in den Monaten danach: Änderungen dauern kürzer, Onboarding neuer Entwickler geht schneller, die Fehlerrate sinkt. Genau deshalb braucht Refactoring einen Sponsor auf Geschäftsführungsebene, der diese Verzögerung akzeptiert.

Gleichzeitig gibt es Refactoring, das sich nicht rechnet. Code, der seit Jahren unverändert läuft und absehbar nicht angefasst wird, braucht keinen Umbau, auch wenn er hässlich ist. Fowler empfiehlt opportunistisches Refactoring: Umgebaut wird dort, wo ohnehin gerade gearbeitet wird oder wo die nächste Änderung ansteht. Die Priorität folgt der Änderungshäufigkeit, nicht dem ästhetischen Empfinden.

Realbeispiel: die Pflichtmigration auf die React Native New Architecture

Wie ein erzwungenes, großflächiges Refactoring aussieht, zeigt die mobile Welt gerade sehr konkret. Meta hat am 8. Oktober 2025 React Native 0.82 veröffentlicht, die erste Version, die ausschließlich auf der sogenannten New Architecture läuft. Die alte Brücke zwischen JavaScript und nativem Code ist seither nicht mehr aktivierbar; die Konfigurationsschalter, mit denen sich die Legacy Architecture bisher erzwingen ließ, werden ignoriert. Das Expo-Team dokumentiert in seinem Leitfaden zur New Architecture, dass Expo SDK 54 die letzte Version ist, in der sich die alte Architektur noch abschalten lässt, und dass SDK 55 vollständig auf React Native 0.83 und damit nur noch auf der New Architecture läuft. Nach Angaben von Expo nutzten im Januar 2026 bereits rund 83 Prozent der mit EAS Build gebauten SDK-54-Projekte die New Architecture.

Für Unternehmen mit einer React-Native-App ist das ein klassisches verhaltenserhaltendes Refactoring: Die App soll für Nutzer exakt gleich funktionieren, aber intern auf eine neue Laufzeit umgestellt werden. Die empfohlene Vorgehensweise folgt genau der Fowler-Mechanik. Zuerst auf React Native 0.81 beziehungsweise Expo SDK 54 heben, dort die New Architecture einschalten, jede Abweichung testen und beheben, inkompatible Bibliotheken über das React Native Directory identifizieren und ersetzen, und erst dann auf 0.82 gehen. Wer die Schritte überspringt, findet Fehler nicht mehr lokalisierbar, weil zu viel auf einmal geändert wurde. Für eine native App ohne JavaScript-Schicht stellt sich dieselbe Logik bei jeder Target-SDK-Hebung oder bei Swift- und Kotlin-Hauptversionen. Wer sich bei einer solchen Migration Unterstützung holen will, findet bei unserer App-Entwicklung Teams, die genau diese Umstellungen regelmäßig durchführen.

Das Beispiel zeigt auch, warum Refactoring nicht beliebig aufschiebbar ist. Expo hat die Legacy Architecture eingefroren, sie erhält weder neue Funktionen noch Fehlerbehebungen, und viele verbreitete Bibliotheken unterstützen nur noch die neue Variante. Wer wartet, zahlt die Migration später trotzdem, nur mit mehr Abhängigkeiten, die gleichzeitig brechen. Technische Schuld hat in solchen Fällen einen festen Fälligkeitstermin.

Häufige Fragen

Wie überzeuge ich die Geschäftsführung von Refactoring, wenn es kein Feature liefert?

Mit Zahlen aus dem eigenen Haus. Miss, wie lange vergleichbare Änderungen in sauberen und in verwahrlosten Modulen dauern, wie viele Produktionsfehler aus welchem Teil des Systems stammen und wie viel Zeit das Team für Wartung statt Entwicklung aufwendet. Die Umfragewerte von rund 30 Prozent Wartungsanteil sind ein brauchbarer Startpunkt, die eigene Zahl ist überzeugender. Verkaufe Refactoring außerdem nicht als Projekt, sondern als Bestandteil jeder Änderung, der in der Schätzung bereits enthalten ist. Dann gibt es keinen separaten Posten, der gestrichen werden kann.

Kann Refactoring Fehler verursachen?

Ja, wenn es ohne Tests oder in zu großen Schritten passiert. Die Methode selbst ist auf Sicherheit angelegt: kleine, verhaltenserhaltende Umbauten mit Testlauf nach jedem Schritt. Fehler entstehen, wenn gleichzeitig Funktionen geändert werden, wenn Tests fehlen oder wenn ein „Refactoring“ in Wahrheit ein halber Rewrite ist. Ein weiterer Risikofaktor sind Schnittstellen nach außen, etwa eine öffentliche API: Ein Rename dort ist kein Refactoring mehr, weil er das Verhalten für Konsumenten ändert. Solche Stellen brauchen eine Übergangsphase mit alter und neuer Signatur.

Wie viel Zeit sollte ein Team für Refactoring einplanen?

Eine feste Quote ist weniger hilfreich als eine Regel. Fowlers Empfehlung lautet, Refactoring an die laufende Arbeit zu koppeln: Wer ein Modul ändert, hinterlässt es etwas besser, als er es vorgefunden hat. In der Schätzung einer Aufgabe ist das enthalten, nicht extra ausgewiesen. Ergänzend lohnt sich ein kleines, bewusst priorisiertes Kontingent für Dependency-Upgrades und Plattformpflege, etwa Target-SDK-Hebungen bei Apps, weil diese Arbeiten Fristen von außen haben. Ein Richtwert aus der Praxis liegt bei 10 bis 20 Prozent der Kapazität; wichtiger als die Zahl ist, dass der Posten im Sprint sichtbar ist und nicht bei jedem Engpass als Erstes gestrichen wird.

Weiterführende Artikel