
Refactoring – der Schlüssel zu sauberem Code

Richard Gross ist Head of Software Archaeology und arbeitet seit 2013 im Bereich der IT-Modernisierung. Als Mitglied der Bereichsleitung treibt er Themen wie technische Exzellenz voran. Als Teamleiter und Architekt unterstützt er Teams dabei, so früh und kontinuierlich wie möglich einen Return on Investment zu erzielen. Um dies zu erreichen, coacht er Teams in den Bereichen Codequalität, Testautomatisierung und Collective Ownership. Sein technischer Fokus liegt auf hexagonalen Architekturen, TestDSLs, Hypermedia-APIs und der ausdrucksstarken und eindeutigen Modellierung der Domäne als Code. Richard teilt sein Wissen durch aktives Pair Programming sowie durch Schulungen, Fachartikel und Präsentationen auf internationalen Konferenzen. Er engagiert sich seit langem auch in dem Open-Source-Projekt CodeCharta, das es Nicht-Entwicklern ermöglicht, ein Verständnis für die Qualität ihrer Software zu gewinnen.
Stell dir vor, dein Code ist wie ein altes Lagerhaus: Anfangs sauber und organisiert, aber inzwischen ein einziges chaotisches Durcheinander. Refactoring bringt Ordnung in dieses Chaos, verbessert die Codequalität und ermöglicht es deinem Team, effizient zu arbeiten, ohne auf unerwartete Probleme zu stoßen.
Erfahre in diesem Ratgeber alles über Code-Refactoring! Entdecke, wie du aus einem chaotischen Lagerhaus ein perfekt organisiertes Warenhaus machst und endlich alles wieder seinen Platz hat.
Definition: Refactoring
Refactoring, auch Refaktorierung, bedeutet auf Deutsch „Umstrukturierung“ – und damit erklärt sich die Sache fast schon von selbst.
Beim Refactoring von Code wird der existierende Code nämlich mit vielen für sich gesehen winzigen Schritten, sogenannten Refactorings, umstrukturiert, ohne dabei seine grundlegende Funktionalität zu verändern. Ziel ist es, die Verständlichkeit des Codes zu erhöhen und somit eine langfristig ressourcenschonende Weiterentwicklung zu ermöglichen.
In der Praxis bedeutet das, dass der Code aufgeräumt und die Softwarequalität verbessert wird, ohne dass die Nutzer des Systems irgendwelche Änderungen an der Funktionalität bemerken. Dies umfasst beispielsweise:
- das Umbenennen von Variablen,
- das Einführen neuer Abstraktionen,
- die Verringerung der Verschachtelungstiefe und
- das Entfernen ungenutzter Codestellen.
Ziel ist es, die technische sowie Domänensprache so klar wie möglich zu modellieren, damit Teams immer handlungsfähig bleiben und neue Funktionen einbauen können.
Wann brauche ich eine Refaktorierung?
Stell dir vor, dein Code ist wie eine Bibliothek. Am Anfang sind alle Bücher ordentlich in den Regalen sortiert: Romane, Sachbücher und Krimis haben ihren festen Platz. Doch mit der Zeit werden Bücher einfach irgendwo hingestellt und niemand weiß mehr, wo, was zu finden ist. Nervig, oder?
Doch kein Grund, gleich eine komplett neue Softwareentwicklung zu starten, denn hier kommt Refactoring ins Spiel. Denn Code, der über einen längeren Zeitraum nicht gepflegt wird, kann ebenso chaotisch werden wie die eben genannte Bibliothek. In diesem Fall lässt die Codequalität stark nach, das Verständnis schwindet und die Komplexität steigt.
Spätestens zu diesem Zeitpunkt häufen sich die Beschwerden über den sogenannten „Spaghetti-Code“. Und das aus gutem Grund! Denn dieser verursacht einen erheblichen Anstieg des Implementierungsaufwands, erschwert die Fehlerbehebung und verhindert ein effizientes Arbeiten. Kurz gesagt: Es kommt zu einer zunehmenden Handlungsunfähigkeit.

Manchmal ist eine Software-Modernisierung notwendig
Falls Sie auf Probleme wie unzureichende Sicherheitsstandards, eingeschränkte Skalierbarkeit oder fehlende Integration mit neuen Technologien stoßen, ist eine einfache Refaktorierung nicht ausreichend. In diesem Fall ist eine Software-Modernisierung notwendig, da veraltete Software die Effizienz Ihres Unternehmens erheblich beeinträchtigen kann.
Vorteile und Ziele des Refactorings
Seien wir ehrlich: Stakeholder wünschen sich, dass neue Anforderungen schnell, unkompliziert und kostengünstig umgesetzt werden. Eine unübersichtliche und schwer verständliche Codebasis ist dabei eher hinderlich, weshalb die Bedeutung des Refactorings in der Softwareentwicklung nicht unterschätzt werden sollte.
Ob bei der Fehlerbehebung, der Implementierung neuer Funktionen oder während eines Reviews – Refactoring sollte in jeder Phase der Softwareentwicklung berücksichtigt werden. Denn es bringt eine Vielzahl von Vorteilen, welche die Software verbessern:
- Komplexitätsreduktion und Verständlichkeit: Die Komplexität des Codes wird reduziert, wodurch seine Verständlichkeit steigt. Dies erleichtert die Zusammenarbeit im Team und vereinfacht die Wartung.
- Testbarkeit: Eine klarere Struktur sorgt für eine bessere Testbarkeit und hilft, Fehler frühzeitig zu erkennen.
- Fehlerbehebung: Bugs können schneller gefunden und behoben werden, da der Code übersichtlicher ist.
- Ressourcenschonung: Eine optimierte Codebasis senkt den Ressourcenverbrauch und erhöht die Effizienz.
Und das Beste daran: Refactoring kann während der laufenden Entwicklung erfolgen, ohne den Entwicklungsprozess zu unterbrechen.
Methoden des Refactorings
Es gibt zahlreiche Methoden, um bestehende Codestellen umzustrukturieren. Ein guter Startpunkt sind jedoch die folgenden sechs Ansätze:
- Umbenennen: Variablen, Methoden oder Klassen umbenennen, um sie aussagekräftiger und verständlicher zu machen.
- Einbetten: Kompakte und verständliche Codestellen direkt an die aufzurufende Stelle verschieben, anstatt sie in Methoden oder Variablen auszulagern.
- Methoden extrahieren: Komplexe und verwirrende Codestellen als separate Methoden auslagern und durch aussagekräftige Methodennamen beschreiben.
- In lokale Variablen auslagern: Statt Werte ohne Kontext im Code zu lassen, ist es sinnvoll, sie in beschreibenden Variablen zu speichern. Zum Beispiel sollte 3.14 als PI bezeichnet werden.
- Parameter hinzufügen: Wenn sich Daten innerhalb einer Methode häufig ändern, sollten sie als Parameter übergeben werden. Das erweitert die Parameterliste und reduziert die Notwendigkeit, die Methode anzupassen.
- In Feld auslagern: Wiederkehrende Werte in einer Klasse in ein gemeinsames Feld auslagern, um die Wartung zu vereinfachen.
Diese Methoden sollten je nach Bedarf und Projektanforderungen ausgewählt und angewendet werden.

Für den Ausdruck „verständlicher Code“ gibt es keine allgemeingültige Definition. Daher sind die Prinzipien des Clean Codes ein guter Ausgangspunkt, um sich auf Regeln und Strukturen zu einigen.
Die Vorgehensweise beim Refactoring
Wie hat schon Goethe gesagt: Eines schickt sich nicht für alle. Und so ist es auch beim Refactoring von Code.
Das bedeutet, es gibt keine einheitliche Vorgehensweise, die für jedes Projekt geeignet ist. Jedes Projekt erfordert eine individuelle Festlegung der Maßnahmen: was, wie und in welchem Umfang umstrukturiert werden muss. Da es also keine Einheitslösung gibt, handelt es sich hier um einen groben Leitfaden.
Schritt 1: Der Eintritt ins Projekt
Nach dieser Einleitung erscheint es wenig überraschend, dass in einem ersten Schritt des Refactorings ein Überblick über den bestehenden Code und die zugrunde liegenden Prozesse gewonnen werden muss. Hierfür sollten zuerst die wichtigsten Metriken analysiert werden, etwa die:
- zyklomatische Komplexität,
- Verschachtelungstiefe,
- Testabdeckung,
- Dateigrößen sowie
- die Anzahl von Funktionen und Klassen.
Große und komplexe Dateien können ein erstes Anzeichen für einen schwer verständlichen und schwer veränderbaren Code sein.
Diese Analyse ermöglicht es, die Anwendungen isoliert zu betrachten und weitere Entscheidungen zu treffen. In diesem Schritt sollte außerdem geklärt werden, welche Qualitätssicherungsprozesse, wie etwa Code-Reviews, bereits existieren.

Bei MaibornWolff haben wir ein Tool entwickelt, das den Code visuell darstellt: CodeCharta. Mit CodeCharta können wir Probleme und Lösungen auf allen Ebenen klar kommunizieren.
Schritt 2: Priorisierung und Umsetzung
Schritt 3: Integration in den Entwicklungsprozess
Nach der Priorisierung folgt die Integration. Dabei gilt es zu beachten, dass Refactoring am effektivsten ist, wenn es in die tägliche Entwicklungsarbeit integriert wird. Das umfasst:
- die Implementierung,
- die Fehlerbehebung und
- das Testen.
Allerdings hat jede Regel ihre Ausnahmen: So müssen besonders unverständliche oder komplexe Codestellen isoliert und separat umstrukturiert werden. Welche Stellen das betrifft, wurde bereits in der Priorisierung festgehalten.
Schritt 4: Funktionalität erhalten
Schritt 5: Dedizierte Refactoring-Projekte
Wie entsteht Spaghetti-Code überhaupt?
Diese Frage sucht nicht nach einem Schuldigen, und das ist auch gut so. Denn die Frage, warum Code im Laufe der Zeit chaotisch wird, hat keine klare Antwort. Eines steht aber fest: Die meisten Entwickler schreiben guten Code und wissen, dass Refactoring ein notwendiger Teil der Entwicklung ist.
Aber wie kommt es dann zu verwirrendem, komplexem und chaotischem Code? Nun, niemand arbeitet im luftleeren Raum. Entwickler müssen nicht nur einen Clean Code schreiben, sondern auch:
- mit äußeren Einflüssen umgehen,
- festgefahrene Prozesse bewältigen,
- branchenspezifische Anforderungen berücksichtigen,
- das Verständnis und Vertrauen der Stakeholder gewinnen und
- unterschiedliche Interessen unter einen Hut bringen.
Eine echte Herkulesaufgabe also. Erschwerend hinzu kommt, dass Refactoring oft erst nach einiger Zeit seinen Mehrwert zeigt und die Umsetzung zusätzlich verkomplizieren kann.
Hier treffen also Welten aufeinander: Auf der einen Seite stehen guter Code und Wartbarkeit, auf der anderen Seite der Wunsch, Anforderungen möglichst schnell umzusetzen.
Deshalb geht es beim Refactoring auch nicht um Schuldzuweisungen, sondern um das offene Ansprechen von Problemen und das Finden von Lösungen. Das ist auch unsere Devise bei MaibornWolff. Gemeinsam schaffen wir ein Projekt, auf das Sie und Ihr Team stolz sein können.

Machen Sie Schluss mit Spaghetti-Code!
Refactoring – die Herausforderungen
Refactoring steigert also die Code-Qualität und Verständlichkeit, was wiederum die Umsatzgeschwindigkeit von Anforderungen verbessert. So weit, so gut. Aber wo ist der Haken?
Um diese Frage zu beantworten, müssen wir uns zwei verschiedene Ebenen von Herausforderungen ansehen: die technische und die menschliche.
Die technische Ebene
Die technischen Herausforderungen beim Refactoring fangen oft schon vor dem eigentlichen Prozess an. Denn die bittere Wahrheit ist: Je länger man das Refactoring aufschiebt, desto schlimmer wird der Code – besonders bei großen Projekten.
Das Problem wächst unbemerkt, steigert dabei jedoch die Wartungskosten und erhöht die Fehleranfälligkeit. Nun steht man vor der Entscheidung: Refactoring, oder kein Refactoring.
Entscheidungen, Entscheidungen. Falls man sich für ein Software-Refactoring entscheidet, sind dies die Herausforderungen, denen man sich stellen muss:
- Funktionalität beibehalten: Einen Code umzustrukturieren, ohne die Funktionalität zu ändern, klingt einfach, bringt aber viele Schwierigkeiten mit sich.
- Erhöhte Absprache notwendig: Bei ausschweifenden Refactorings ist eine erhöhte Kommunikation zwischen den Entwicklern erforderlich, um sicherzustellen, dass alle Änderungen korrekt umgesetzt werden. Dies kostet Zeit und kann zu längeren Diskussionen führen.
- Notwendigkeit von Tests: Um die Funktionalität zu gewährleisten, müssen vor dem Refactoring umfangreiche Tests durchgeführt werden, was einen zusätzlichen Aufwand bedeutet.
- Merge-Konflikte: Arbeiten in Branches kann Refactorings behindern, da Entwickler Merge-Konflikte fürchten, die beim Zusammenführen der Code-Änderungen entstehen können.
- Qualitätssicherung und Testabdeckung: Fehlendes Vertrauen in die Qualitätssicherung oder lückenhafte Testabdeckung führt dazu, dass Entwickler den Code nicht anpassen, aus Angst, die Funktionalität zu beeinträchtigen.
- Lange Reintegrationszeiten: Große Änderungen durch Refactoring können zu langen Reintegrationszeiten führen, was oft abschreckend wirkt und den Prozess verzögert.
Die menschliche Ebene
Doch wie so oft kommt zur technischen Ebene nun noch die menschliche hinzu. Es sind schließlich Menschen, die von den Vorteilen eines Refactorings überzeugt werden müssen und die endgültige Entscheidung treffen. Und hier tauchen auch schon die ersten Herausforderungen auf:
- Gradual sichtbare Änderungen: Veränderungen durch Refactoring werden oft nur allmählich sichtbar, was häufig dazu führt, dass sie vernachlässigt oder belächelt werden.
- Vertrauen und Zeit: Für erfolgreiches Refactoring ist Vertrauen in das Team und ausreichend Zeit notwendig, um die Vorteile der Veränderungen zu erkennen.
- Erfahrene Entwickler notwendig: Es erfordert erfahrene Entwickler, um die Abhängigkeiten im Code aufzuzeigen und die Notwendigkeit von Refactoring zu kommunizieren.
- Verantwortung aufzeigen: Eine klare Kommunikation der Verantwortung für Refactoring von Code ist entscheidend, um Zeit dafür einzuplanen, insbesondere bei komplexen Projekten.
- Verständnis für ideale Code-Struktur: Auch neuer Code kann Refactoring erfordern, um den langfristigen Qualitätsstandards zu genügen. Entwickler müssen ein wachsendes Verständnis für die ideale Struktur des Codes entwickeln und diese in ihrer Arbeit umsetzen.
Refactoring – alles an seinem Platz
FAQs zum Refactoring
Was ist Refactoring?
Refactoring ist das Umstrukturieren von existierendem Code, um dessen Verständlichkeit und Wartbarkeit zu verbessern, ohne die Funktionalität zu ändern. Es hilft, die Codequalität zu steigern und langfristig effizientere Softwareentwicklung zu ermöglichen.Was ist CodeCharta und wie hilft es beim Refactoring?
CodeCharta ist ein Tool zur Visualisierung von Code, das von MaibornWolff entwickelt wurde. Es hilft, strukturelle Probleme zu erkennen und zu kommunizieren. Zudem unterstützt es Entwickler und Stakeholder dabei, den Zustand und die Fortschritte im Refactoring-Prozess besser zu verstehen.Welche Herausforderungen gibt es beim Refactoring?
Technische Herausforderungen umfassen das Beibehalten der Funktionalität und die Notwendigkeit von Tests. Menschliche Herausforderungen sind u. a. das Gewinnen von Vertrauen und die Akzeptanz der Notwendigkeit durch Stakeholder. Beide Ebenen erfordern erfahrene Entwickler und klare Kommunikation.Was ist der Zweck des Code-Refactorings?
Das Ziel des Code-Refactorings ist es, die interne Struktur des bestehenden Codes zu verbessern, ohne das äußere Verhalten zu verändern. Dies erhöht die Codequalität, Lesbarkeit und Wartbarkeit.