legacy-code.webp
Webentwicklung |

Refactor oder nicht? Vom Umgang mit Legacy-Code und dem Drang, alles schöner zu machen

Benedikt.jpg

Benedikt

13. Januar 2025

tl;dr quick summary
Refactoring kann schnell zur Ablenkung werden – besonders bei Legacy-Code, der dich innerlich anschreit. In diesem Beitrag teilen wir Strategien, wie du mit dem Drang umgehst, alles sofort schöner zu machen, wann sich ein Refactor wirklich lohnt und wie du technische Schulden verständlich kommunizierst. Spoiler: Refactoring ist kein Sprint, sondern ein Langzeitprojekt.

Hinweis: Dieser Artikel wurde unter Zuhilfenahme von KI aus dem Englischen übersetzt. Hier geht's zum Originaltext.

Definition von Legacy Code

Als Softwareentwickler kennen wir alle diesen Moment, wenn wir uns ein Stück unseres Codes ansehen und denken: »Welcher Idiot hat sich entschieden, dieses veraltete Tool zu benutzen«, nur um dann festzustellen, dass wir es selbst waren. Meine Kollegen und ich nennen das den »Ich-will-alles-neu-schreiben«-Faktor. Im Folgenden möchte ich ergründen, wie wir diesen Faktor interpretieren können, ohne zu frustriert davon zu werden. Konkret möchte ich nicht über komplette Projekt-Rewrites sprechen, darüber wird bereits viel diskutiert und das ist ein ganz eigenes Thema. Vielmehr möchte ich über kleinere Code-Updates und technische Schulden sprechen. Natürlich wird sich deine Sichtweise zu diesem Thema im Laufe deiner Karriere verändern, und das ist gut so – es spiegelt die Erfahrung wider, die du gesammelt hast.

spiderman.jpg

In meiner Definition ist das Wesen von Legacy-Code der Gedanke: »Ja, das würde ich heute anders machen«. Es geht nicht nur um alten Code, sondern um Code, der nicht mehr zu den aktuellen Standards, Werkzeugen oder Architekturen passt, die wir bevorzugen. Ob es die Abhängigkeit von einer Bibliothek ist, die mittlerweile von etwas Effizienteren überholt wurde, oder die Verwendung eines Musters, das inzwischen veraltet wirkt – das Erkennen von Legacy-Code ist der erste Schritt auf dem Weg zum Refactoring. Ein weiterer Punkt: Manchmal funktionieren Abhängigkeiten einwandfrei, erhalten aber Updates mit Breaking Changes. Ein Beispiel ist ein Projekt, an dem ich gerade arbeite, das die Fluent UI-Komponentenbibliothek verwendet. Diese Bibliothek ist ein umfassendes Toolkit, das tief in das Projekt integriert ist. Leider erfordert die neueste Version von Fluent UI den Wechsel zu einer neuen CSS-in-JS-Engine, was bedeutet, dass wir fast alle unsere Komponenten über mehrere Teilprojekte hinweg anpassen müssten. Obwohl wir gerne upgraden würden, rechtfertigt der immense Arbeitsaufwand noch nicht den Nutzen – zumindest solange, bis Microsoft beschließt, die ältere Version von Fluent UI einzustellen.

Blackbox-Programmierung akzeptieren

Eine Sache, die hilft, sich auf die aktuelle Aufgabe zu konzentrieren, ohne sich in unnötigen Ablenkungen zu verlieren, ist die Blackbox-Programmierung. Wenn du Informatik studiert hast, kommt dir das vielleicht bekannt vor. Dieser Ansatz betont, bestimmte Teile deines Codes oder Abhängigkeiten als Black Boxes zu behandeln. Mit anderen Worten: Solange diese Komponenten korrekt und effizient funktionieren, musst du dich nicht mit ihren inneren Abläufen beschäftigen. Diese Denkweise ermöglicht es dir, dich auf die aktuelle Aufgabe zu konzentrieren, ohne dich vom Drang ablenken zu lassen, Teile des Codes zu optimieren oder zu aktualisieren,die keine Probleme verursachen. Es ist wichtig, sich selbst daran zu erinnern, dass es – zumindest vorerst – nicht dein Problem ist, solange es funktioniert. Wenn es keinen zwingenden Grund oder eine hohe Priorität gibt, die neuesten Tools oder Technologien einzusetzen, ist es oft am besten, gut funktionierende Dinge in Ruhe zu lassen. Das bedeutet nicht, potenzielle Verbesserungen auf ewig zu ignorieren, sondern eher, die Arbeitslast effektiv zu priorisieren. Durch die Anwendung der Prinzipien der Blackbox-Programmierung kannst du sicherstellen, dass deine Bemühungen darauf gerichtet sind, die dringendsten Probleme zu lösen und Mehrwert zu liefern, ohne dich von der Verlockung der neuesten, glänzendsten Tools ablenken zu lassen. Um diese Punkte zu ergänzen:

Frag dich, ob es wirklich notwendig ist, eine Abhängigkeit oder einen Codestil auszutauschen, oder ob du einfach nur mit den neuesten Spielzeugen spielen möchtest.

Ich selbst beantworte diese Frage regelmäßig mit Letzterem. Frag dein Team, um ein besseres Gefühl zu bekommen.

Narzissmus der kleinen Code-Unterschiede

Oft ertappe ich mich dabei, dass ich kleine Gewohnheiten meiner Kollegen beim Schreiben von Code ändern möchte. Die meisten dieser Probleme sollten idealerweise durch ein robustes Linting- und Code-Formatter-Setup behandelt werden, aber gelegentlich rutschen einige Eigenheiten durch die Maschen und hinterlassen bei mir ein gewisses Gefühl der Frustration. Es könnte etwas so Einfaches sein wie eine eigenwillige Namenskonvention oder eine andere Programmierphilosophie, die nicht mit meinen eigenen Vorlieben übereinstimmt. Diese Unterschiede, obwohl meist gering, können manchmal dazu führen, dass sich der Code einfach nicht richtig anfühlt.

Es ist jedoch wichtig, sich daran zu erinnern, dass viele Wege nach Rom führen. Programmieren ist ebenso eine Kunst wie eine Wissenschaft, und es gibt oft mehrere gültige Ansätze, um dasselbe Problem zu lösen. Es ist wichtig zu erkennen, dass diese kleinen Unterschiede den Code nicht unbedingt falsch machen – nur anders. Diese Vielfalt an Programmierstilen zu akzeptieren kann tatsächlich von Vorteil sein und Kreativität und Innovation im Team fördern.

Anstatt zuzulassen, dass sich diese kleinen Irritationen aufbauen, kann es produktiver sein, sich auf das große Ganze und die Funktionalität des Codes zu konzentrieren. Manchmal musst du aus deiner Komfortzone heraustreten und die unterschiedlichen Perspektiven schätzen, die deine Kollegen einbringen. Denk daran, dass das ultimative Ziel darin besteht, einen funktionalen, effizienten und wartbaren Code zu erstellen, nicht einen einheitlichen Stil durchzusetzen. Indem du diese kleinen Unterschiede nicht zu ernst nimmst, kannst du eine kollaborativere und harmonischere Arbeitsumgebung fördern.

Es ist schwieriger, Code zu lesen als zu schreiben.

Eine sehr gute Lektüre zu diesem Thema ist The Narcissism of Small Code Differences von Reg Braithwaite.

Wie man mit dem Kunden kommuniziert

Die Kommunikation der Notwendigkeit von Refactoring gegenüber Kunden ist ein weiterer kritischer Aspekt. Kunden sehen Refactoring oft als Ausgabe ohne direkten, unmittelbaren Nutzen, was Transparenz und Aufklärung zu Schlüsselfaktoren macht. In einer perfekten Welt hätte ich gerne von Anfang an ein Wartungsbudget. Jedes Softwareprojekt wird früher oder später eine Art von Pflege benötigen. Beginne damit, das Konzept der technischen Schulden zu erklären und wie diese, ähnlich wie finanzielle Schulden, mit der Zeit Zinsen in Form von langsamerer Entwicklung, höheren Kosten und erhöhtem Ausfallrisiko ansammeln. Technische Schulden bedeuten übrigens nicht, dass du am Anfang falsche Entscheidungen getroffen hast, sondern dass du nach bestem Wissen gehandelt hast. Gib konkrete Beispiele dafür, wie sich Legacy-Code auf das Projekt auswirken wird und welche Verbesserungen sie von Refactoring und Wartung erwarten können. Es ist auch vorteilhaft, einen klaren Plan und Zeitrahmen für den Refactoring-Prozess zu skizzieren. Dies sollte eine detaillierte Analyse der kommenden oder aktuellen Probleme, die vorgeschlagenen Änderungen, den erwarteten Zeitaufwand und die Vorteile umfassen. Ein durchdachter Ansatz hilft, Kunden zu versichern, dass es sich nicht nur um Beschäftigungstherapie handelt, sondern um einen strategischen Schritt, um den langfristigen Erfolg des Projekts zu sichern.

Auch wenn es "deine" Codebasis ist, bleibt deine Schätzung, wie lange es dauern wird, nur eine Schätzung. Bitte sei vorsichtig mit Schätzungen und füge einen angemessenen Unsicherheitspuffer hinzu. Der Zeitpunkt, wann refaktorisiert werden soll, ist entscheidend. Ein Refactoring während einer kritischen Projektphase kann unnötige Störungen verursachen, während eine Verzögerung zu größeren Problemen führen kann. Eine gute Faustregel ist, Refactoring in Betracht zu ziehen, wenn die Legacy-Komponente beginnt, neue Entwicklungen zu behindern, Fehler verursacht, die schwer zu beheben sind, oder wenn es einen klaren, berechtigten Vorteil in Bezug auf Leistung, Skalierbarkeit oder Wartbarkeit gibt. Ich möchte hier besonders die Wartbarkeit hervorheben. Diese Entscheidung sollte datengesteuert sein; Metriken wie die Häufigkeit von Problemen oder einfach wie oft ihr im Team über etwas sprecht, können den Zeitpunkt bestimmen.

Blick nach vorne

Schließlich ist es wichtig zu bedenken, dass Refactoring keine einmalige Aufgabe ist, sondern ein fortlaufender Teil des Software-Entwicklungszyklus. Mit der Weiterentwicklung der Technologie werden neue Tools und Methoden auftauchen, die Teile der Codebasis wieder veralten lassen. Regelmäßige Code-Reviews und Updates können dazu beitragen, technische Schulden überschaubar zu halten. Wenn du Kunden mit regelmäßigen Berichten über den Zustand der Codebasis und die Vorteile früherer Refactorings auf dem Laufenden hältst, kann das zu einem besseren Verständnis und einer höheren Wertschätzung für diese Bemühungen führen. Letztendlich sorgt ein proaktiver Ansatz beim Umgang mit Legacy-Code für ein robustes, flexibles und zukunftssicheres Softwareprodukt. Genau das wollen wir alle – als glückliche Entwickler und glückliche Kunden.

Wenn dir dieser Artikel gefallen hat, könnte dir auch der Beitrag meines Kollegen über die Evolution von Datenmutationen mit Formularen in React gefallen.

Anmerkung: 🤖 Hinweis zur Verwendung von KI in diesem Artikel: Dieser Artikel wurde von Menschen geschrieben (Danke an Leo und Irena), einschließlich des Titels, der Konzepte und der Codebeispiele. Allerdings haben wir KI verwendet, um den Schreibstil zu verbessern.

Weitere Themen

Lea, 04.04.2025

Vue clever nutzen – Wiederverwendbarkeit für Einsteiger:innen

Vue

JavaScript

Reusability

DRY Principle

Components

Composables

Zum Blogartikel
Header-top-ten-mistakes-to-avoid.png

Francesca, Ricarda, 02.04.2025

Die 10 häufigsten Fehler bei der Entwicklung digitaler Produkte – und wie du sie vermeidest

MVP development

UX/UI design

product vision

agile process

user engagement

product development

Zum Blogartikel

Judith, 31.03.2025

Von der Hypothese zur echten Erkenntnis: MVPs richtig einsetzen

Zum Blogartikel