Code-Refactoring ist ein Verfahren in der Softwareentwicklung, bei dem die interne Struktur von Softwarecode verändert wird, ohne sein äußeres Verhalten zu ändern oder seine Funktionen zu beeinträchtigen. Diese kleineren Änderungen zielen darauf ab, den Code lesbarer und wartbarer zu machen.
Martin Fowler hat diese Praxis durch sein Buch „Refactoring“ populär gemacht, das erstmals 1999 veröffentlicht wurde. Code-Refactoring kann helfen, sogenannte „Code Smells“ (übersetzt etwa „Codegerüche“) zu beseitigen, die Fowler als „ein oberflächliches Anzeichen, das in der Regel auf ein tiefer liegendes Problem im System hinweist“ definiert. Er fügt hinzu, dass diese Code Smells „schnell zu erkennen oder erschnüffelbar“ sind und nennt lange Methoden und Klassen, die nur Daten und kein Verhalten enthalten, als Beispiele für Code Smells.
Beispiele für das Refactoring von Code sind das Korrigieren falscher Formatierungen, das Umbenennen nicht beschreibender Variablen, das Entfernen doppelter oder nicht verwendeter Funktionen und das Aufteilen großer, langer Methoden in kleinere, besser handhabbare Blöcke. Diese trivialen, verhaltenswahrenden Änderungen führen zwar seltener zu einem Bruch des Codes oder zu Fehlern, aber ihre schrittweise Wirkung kann zu einer Optimierung der Softwareleistung beitragen.
Refactoring mag wie ein einfaches Unterfangen erscheinen. Aber einige Taktiken können Softwareentwicklern zu einem strategischen Ansatz verhelfen:
Abstraktion ist ein grundlegendes Konzept in der objektorientierten Programmierung. Es beinhaltet die Verallgemeinerung von Objekten, sodass komplexe Details ausgeblendet werden und nur die wesentlichen Informationen übrig bleiben.
Beim Coderefactoring wird die Abstraktion in der Regel für große Codebasen implementiert. Es besteht aus 2 Mechanismen:
Bei diesem modularen Ansatz werden große Codeblöcke in kleinere zerlegt oder aufgeteilt, um sie einfacher und besser handhabbar zu machen. Die Extraktionsmethode und die Inline-Methode sind 2 Ansätze für die Komposition:
Bei dieser Technik werden Attribute, Methoden und andere Funktionen zwischen Klassen verschoben, um Abhängigkeiten zu verringern und den Zusammenhalt innerhalb der Funktionen einer Klasse und zwischen den Klassen zu verbessern. Diese Umverteilung trägt zu einem logischeren und ausgewogeneren Design des vorhandenen Codes bei und erleichtert dessen Erweiterung und Pflege.
Red-Green-Refactor lehnt sich an die testgetriebene Entwicklung an, bei der Tests vor dem eigentlichen Quellcode geschrieben werden. Es handelt sich um eine iterative Strategie, die ein kontinuierliches Refactoring und Testen ermöglicht.
Dieser dreistufige Prozess umfasst die folgenden Schritte:
Das Ziel besteht darin, den Code und die damit verbundene Logik zu vereinfachen. Dies kann in Form einer Reduzierung der Anzahl von Parametern in einer Methode, der Umbenennung von überlangen Variablen oder Methoden, der Kombination von bedingten Ausdrücken, die zum gleichen Ergebnis führen, der Entkopplung komplexer bedingter Fragmente oder sogar der Verwendung von Polymorphismus anstelle von Bedingungen geschehen.
Stellen Sie sich Code-Refactoring so vor, dass jeden Tag ein Raum aufgeräumt wird, um das Aufräumen am Ende der Woche viel einfacher und schneller zu gestalten. Das Ziel von Code-Refactoring ist es, die technische Verschuldung zu reduzieren, die entsteht, wenn Programmierer Abkürzungen verwenden, z. B. Logik duplizieren, Codierungsstandards nicht befolgen oder unklare Variablennamen verwenden.
Im Folgenden finden Sie einige Vorteile, die Software-Entwicklungsteams aus dem Code-Refactoring ziehen können:
Refactoring kann zu einfacherem Code führen. Dies hilft Entwicklern, große Codebasen besser zu verstehen. Auch neu eingestellte Programmierer profitieren davon, da sie schnell das Innenleben von unbekanntem Code erfassen können.
Code-Refactoring legt den Grundstein für eine bessere Wartung. Ein klarer Code erfordert weniger Aufwand beim Debugging, der Implementierung einer neuen Funktion, der Aktualisierung bestehender Funktionen oder der Umstellung auf die neuesten Technologien. Wie bei der vorbeugenden Wartung in der Fertigung ermöglicht das Refactoring des Codes jetzt kleinere Korrekturen, um größere Fehler in der Zukunft zu vermeiden.
Wenn Code ein Refactoring durchlaufen hat, ist er sauberer und dadurch leichter zu verstehen und zu bearbeiten. Er ist zudem einfacher zu navigieren, was wiederum zu einer Optimierung des Softwareentwicklungsprozesses beiträgt.
Ein Refactoring hat möglicherweise keine so bedeutenden Auswirkungen wie tatsächliche Codeoptimierungen, die auf die Leistung abzielen. Einfacherer, weniger sperriger Code kann jedoch dennoch zu effizienterer Software und schnelleren Laufzeit beitragen.
Refactoring kann zu klarem und sauberem Code führen, aber das Verfahren ist nicht ohne Nachteile. Hier sind einige Herausforderungen, auf die Entwicklungsteams beim Refactoring von Code stoßen können:
Die Teams müssen entscheiden, wer am Code-Refactoring-Prozess teilnimmt und welche Aufgaben und Verantwortlichkeiten sie haben. Dies kann dazu führen, dass Programmierer von wichtigen Softwareentwicklungsaufgaben abgezogen werden – ein Kompromiss, den sich kleinere Teams möglicherweise nicht leisten können.
Selbst die kleinste Codeänderung birgt das Risiko, dass ein neuer Fehler eingeführt wird oder ein vorhandener Fehler wieder auftaucht. Bei einer komplexeren Code-Überarbeitung besteht auch die Möglichkeit, Features und Funktionen zu beschädigen oder zu verändern.
Veralteter Code bezieht sich auf alte Codebasen, die noch ihren Zweck erfüllen, aber mit veralteten Technologien entwickelt wurden und nicht mehr aktiv unterstützt oder gewartet werden. Beim Refactoring kann es zu Abhängigkeits- und Kompatibilitätsproblemen kommen. Dies erfordert eine gründlichere Codeanalyse und einen detaillierten Plan, um alle den veralteten Code betreffenden Änderungen vorzunehmen.
Es kann verlockend sein, mehr als nötig zu reparieren, vor allem, wenn kein Plan vorhanden ist oder keine klaren Ziele festgelegt wurden. Insbesondere bei der logischen Umstrukturierung kann sich der Umfang ausweiten, wenn die Programmierer sich keine Zeit für die Untersuchung des Codes und die Ermittlung der verbesserungswürdigen Bereiche genommen haben.
Das Code-Refactoring kann viel Zeit in Anspruch nehmen, die den meisten Entwicklungsteams fehlt. Sie müssen die Notwendigkeit des Refactorings mit der Einhaltung der Projektfristen in Einklang bringen und abwägen, wann und wie viel überarbeitet werden soll.
Bevor Sie sich auf den Weg zum Code-Refactoring machen, sollten Sie die folgenden Tipps beachten, um die Herausforderungen bei diesem Prozess zu meistern:
Der Zeitpunkt für das Refactoring von Code ist ebenso wichtig wie das Warum oder Wie. Es kann Teil der regelmäßigen Wartungsaktivitäten eines Software-Entwicklungsteams sein oder in Code-Reviews integriert werden.
Das Refactoring ist auch ein Muss, bevor neue Funktionen hinzugefügt, umfangreiche Updates implementiert, auf neuere Stacks umgestellt oder Programmierschnittstellen (APIs) oder Bibliotheken aktualisiert werden. Sie schafft einen skalierbaren und anpassungsfähigeren Framework, auf dem in Zukunft aufgebaut werden kann.
Das Code-Refactoring kann zeitaufwändig sein, was eine entsprechende Planung voraussetzt. Entwicklungsteams müssen ihre Ziele und den Umfang berücksichtigen. Sie können in kleinen Schritten vorgehen und sich ein paar Tage lang auf winzige Änderungen wie das Löschen von totem Code, die Korrektur von Formatierungen oder das Entfernen von Duplikaten konzentrieren. Wenn es sich um eine umfangreichere Bereinigung handelt, dann wird das Refactoring zu einem Projekt mit Fristen und einem längeren Zeitrahmen.
Einfache Refactoring-Aufgaben erfordern vielleicht nicht viel Analyse. Bei Techniken, die sich auf die Logik beziehen, ist es jedoch unerlässlich, den gesamten zugehörigen Code zu verstehen. Die Ermittlung des Grundprinzips hinter der Codestruktur kann Programmierern zu fundierteren Entscheidungen und gezielteren Änderungen verhelfen.
Auch die Befolgung der Codierungsstandards und Designprinzipien eines Teams kann die Integrität bewahren und die Architektur der Codebasis beibehalten.
Beim Refactoring geht es nicht nur um die Verbesserung des Codes, sondern auch um die Verbesserung des Codes. es geht auch darum, dafür zu sorgen, dass diese Verbesserungen funktionieren. Deshalb sind Tests wichtig, um zu bestätigen, dass die Software selbst und ihr Verhalten intakt bleiben.
Die Entwickler können zwar ihre eigenen Integrations- und Unit-Tests durchführen, aber die Einbeziehung des QA-Teams ist entscheidend. Sie können funktionale Tests zur Überprüfung von Funktionen durchführen sowie Regressionstests, um zu prüfen, ob der umstrukturierte Code keine Fehler einführt oder Funktionen beeinträchtigt.
Auch die Dokumentation von Änderungen muss Teil des Prozesses sein. Dies erleichtert die Nachverfolgung von Änderungen und ermöglicht ein reibungsloseres Code-Refactoring in der Zukunft.
Mehrere Tools können dabei helfen, die Code-Refaktorierung zu beschleunigen und zu automatisieren. Hier sind einige beliebte:
Viele der heutigen IDEs verfügen bereits über eine integrierte Unterstützung für automatisiertes Refactoring, ohne dass Code beschädigt oder Fehler eingeführt werden. Einige bieten sogar KI-gestützte Refactoring-Empfehlungen.
Zu den IDEs, die für das Code-Refactoring verwendet werden können, gehören IntelliJ IDEA für Programmiersprachen, die auf der Java Virtual Machine (JVM) basieren, PyCharm für Python und die ReSharper Visual Studio-Erweiterung für C#, C++ und .NET.
Statische Analysatoren bewerten den Code, ohne ihn auszuführen. Diese Analysatoren erkennen häufige Programmierfehler und Probleme mit der Codequalität und ermöglichen den Entwicklern, diese frühzeitig im Softwareentwicklungsprozess zu beheben.
Beispiele für statische Codeanalysatoren sind Codacy und das Open-Source-PMD, die beide mehrere Programmiersprachen unterstützen, JArchitect für Java, NDepend für .NET und den RuboCop Linter and Formatter für Ruby.
Refactoring.com ist die Website von Martin Fowler, die einen Online-Katalog mit Refactoring-Methoden aus seinem Buch enthält. Refactoring.Guru ist eine weitere Website, auf der Refactoring-Techniken und Designmuster besprochen werden.
Künstliche Intelligenz (KI) kann beim Code-Refactoring-Prozess helfen. Generative KI-Anwendungen basieren auf großen Sprachmodellen (Large Language Models, LLMs), die komplexe oder große Codebasen analysieren und die Semantik und den Kontext dahinter verstehen können. Auf dieser Grundlage liefern sie umgehend Refactoring-Empfehlungen in Echtzeit.
IBM® Bob beispielsweise identifiziert Fehler und Verbesserungsmöglichkeiten. Anschließend werden gezielte Fixes vorgeschlagen, die mit den etablierten Codierungskonventionen des Teams übereinstimmen und so das Code-Refactoring vereinfachen und beschleunigen. Zu den weiteren ähnlichen KI-Refactoring-Tools gehören Amazon CodeGuru Reviewer, GitHub Copilot und ChatGPT von OpenAI.
Für diejenigen, die mit veraltetem Code zu tun haben, verbindet IBM watsonx Code Assistant for Z generative KI und Automatisierung, um Entwicklern bei der Modernisierung ihrer Anwendungen zu helfen. Der watsonx Code Assistant for Z Understand ermöglicht es Programmierern, ihre Anwendung in modulare und wiederverwendbare Dienste umzugestalten. Er verwendet Codeanalyse-Algorithmen, um COBOL-Anwendungen zu modernisieren.
Wie bei jedem KI-System müssen die Entwickler die Ergebnisse der KI-gestützten Code-Refactoring-Tools auf ihre Genauigkeit hin überprüfen. Zudem sind Tests erforderlich, um sicherzustellen, dass alle vorgeschlagenen Änderungen wie erwartet funktionieren.
Befähigen Sie Ihre Teams, schneller innovativ zu sein – mit IBM Bob, das KI-gestützte Anwendungsmodernisierung, schnelle Entwicklung und eine effizientere Softwarebereitstellung ermöglicht.
Nutzen Sie generative KI, um die Anwendungsmodernisierung zu optimieren, und unterstützen Sie so Entwicklungsteams dabei, den Wandel zu beschleunigen, die Produktivität zu steigern und die Komplexität zu verringern.
Gestalten Sie Altsysteme durch intelligente KI-Modernisierung neu.