Start / Seminare / KI-gestütztes Refactoring und Legacy-Modernisierung
Modul
Kleine, verhaltenserhaltende Refactorings
8 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Kleine, verhaltenserhaltende Refactorings
0:00 Jetzt fassen wir zum ersten Mal Code an. Und wir tun es mit dem unspektakulärsten Werkzeugkasten, den es gibt: umbenennen, herausziehen, einen Parameter einführen. Nichts davon wird Sie beeindrucken. Genau das ist der Punkt. Diese Schritte sind so klein, dass sie nicht scheitern können — und ihre Wirkung entsteht durch Wiederholung.
0:19 Eine unübersichtliche Funktion wird nicht durch einen großen Wurf lesbar, sondern durch fünfzehn dieser Schritte hintereinander. In diesem Modul geht es um dieses Handwerk und um die Frage, welchen Teil davon Sie besser einem Werkzeug überlassen als einem Sprachmodell.
Kleine, verhaltenserhaltende Refactorings
0:35 Der Aufbau folgt dem Nutzen. Zuerst das Grundrepertoire und die Umbenennung, die von allen kleinen Umbauten die unterschätzteste ist. Dann zwei Themen, bei denen sich Urteilsvermögen zeigt: Duplikation bewerten und Seiteneffekte isolieren. Dann der Umbau mit der höchsten Irrtumsquote überhaupt — toten Code entfernen. Danach die Arbeitsteilung zwischen Werkzeug und Agent.
0:57 Und zum Schluss die Regel, an der alles hängt: ein Refactoring pro Schritt. In der Übung arbeiten Sie einen Befundkatalog ausdrücklich nicht ab, sondern bewerten ihn.
Das Grundrepertoire
1:08 Fangen wir mit dem Handwerkskasten an. Fünf Schritte, die jede erfahrene Entwicklerin kennt — und deren eigentliche Qualität leicht übersehen wird, weil sie so gewöhnlich sind. Diese Umbauten sind klein, weil sie sich mechanisch und mit hoher Sicherheit ausführen lassen. Und darin liegt ihr Wert: Jeder ist in Sekunden geprüft, und wenn etwas schiefgeht, ist der Weg zurück kurz.
1:30 Das klingt bescheiden, ist aber genau die Eigenschaft, die in einem ungetesteten Bestandssystem zählt. Sie kaufen sich mit jedem dieser Schritte eine Position, zu der Sie zurückkehren können. Die Wirkung entsteht durch Wiederholung — und die fällt einem beim Zusehen gar nicht auf, weil kein einzelner Schritt beeindruckend ist.
1:49 Schauen Sie sich die rechte Spalte an — dort steht, was der Schritt eigentlich bewirkt, jenseits der Optik. Ein Ausdruck, der in eine benannte Variable wandert, erklärt eine Bedingung ohne Kommentar. Ein herausgezogener Abschnitt schafft einen Testpunkt, wo vorher keiner war — das ist die Verbindung zu Modul vier. Ein eingeführter Parameter löst eine versteckte Abhängigkeit auf. Und die vorgezogene Abbruchbedingung senkt die Verschachtelungstiefe, ohne am Verhalten zu rühren.
2:17 Keiner dieser Schritte ist spektakulär, und alle fünf zusammen, mehrfach angewandt, verändern ein Modul grundlegend. Der erste Punkt ist der, den Sie sich merken sollten, weil er so verführerisch ist: zwei Schritte bündeln, weil sie zusammenpassen. Sie passen ja auch zusammen — und trotzdem verlieren Sie damit die Diagnosefähigkeit, über die wir in Kapitel sieben sprechen.
2:39 Der dritte Punkt betrifft die Haltung: Manche warten auf die große, saubere Lösung, weil die kleinen Schritte unbedeutend wirken. Diese Lösung kommt nie. Und der vierte ist rein praktisch: Ohne Commits nach jedem Schritt haben Sie den kurzen Rückweg verloren, der der ganze Vorteil dieser Methode ist.
Namen als Ergebnis des Verstehens
2:56 Jetzt zu dem Schritt, den die meisten für Kosmetik halten. Er ist in Wirklichkeit die Stelle, an der Erkundungswissen in den Code zurückfließt — und damit dauerhaft wird. Erinnern Sie sich an die 3,5 aus Modul zwei — die nackte Zahl in einer Bedingung zur Fahrzeugklasse? Wenn daraus eine benannte Grenze wird, passiert mehr als eine optische Verbesserung. Sie haben Wissen, das Sie sich mühsam erarbeitet haben, in ausführbare Form gebracht.
3:22 Es steht jetzt nicht in Ihrem Kopf und nicht in einem Dokument, das niemand liest, sondern an genau der Stelle, an der die nächste Person darüber stolpert. Ein guter Name ist deshalb kein Schmuck. Er ist das Protokoll dessen, was Sie verstanden haben. Es gibt einen praktischen Grund, mit dem Benennen anzufangen, und er hat mit dem Rhythmus der Arbeit zu tun.
3:43 Sie verstehen eine Sache, geben ihr einen Namen — und der nächste Schritt fällt leichter, weil der Code jetzt mitspricht. Nach zehn Benennungen ist aus einer undurchdringlichen Funktion ein Text geworden, den man lesen kann. Der vierte Punkt ist wichtig für die Werkzeugwahl: Eine Umbenennung durch die Entwicklungsumgebung ist der sicherste Umbau überhaupt, weil sie auf dem Syntaxbaum arbeitet.
4:05 Eine Textersetzung ist etwas völlig anderes und trägt diese Sicherheit nicht. Der erste Punkt ist der ernsteste: Wer benennt, bevor er verstanden hat, zementiert seinen Irrtum. Ein falscher Name ist schlimmer als eine nackte Zahl, weil ihm die nächste Person glaubt. Wenn Sie unsicher sind, notieren Sie den Zweifel im Unknowns Register und warten Sie mit der Benennung. Der zweite Punkt: Namen kommen aus der Fachlichkeit, nicht aus der Technik.
4:31 „Schwellenwert eins“ ist kein Fortschritt. Und der dritte ist die Werkzeugfrage von eben — projektweites Suchen und Ersetzen erwischt zuverlässig auch Dinge, die zufällig gleich heißen.
Duplikation bewerten statt beseitigen
4:42 Kommen wir zum ersten Thema, bei dem Urteilsvermögen gefragt ist — und bei dem ein Agent Ihnen zuverlässig einen Vorschlag macht, der etwa in der Hälfte der Fälle falsch ist. Duplikate zu finden ist einfach, und ein Agent macht das hervorragend. Er schlägt dann auch gleich die Zusammenführung vor, und der Vorschlag sieht technisch stimmig aus.
5:01 Die Frage, die er nicht beantworten kann, ist eine fachliche: Handelt es sich um dieselbe Regel, die zufällig zweimal aufgeschrieben wurde — oder um zwei unabhängige Regeln, die heute zufällig gleich aussehen? Im Bestand ist das schwerer zu entscheiden als in neuem Code, und die Folgen eines Fehlurteils sind größer, weil die zusammengeführte Stelle künftig von zwei Seiten unter Änderungsdruck steht.
5:24 Der Kern steckt in Schritt zwei, und die Formulierung ist wichtig: Wenn sich die eine Stelle fachlich ändert — muss sich die andere zwingend mitändern? Nicht „könnte“, nicht „wahrscheinlich“. Zwingend. Beim Fahrtenbuch könnten zwei Berechnungen heute denselben Steuersatz verwenden — die eine für Firmenwagen, die andere für Privatfahrzeuge. Gleicher Code, zwei unabhängige Regeln.
5:47 Ändert der Gesetzgeber eine davon, ist die Zusammenführung Ihr Problem. Deshalb Schritt fünf: Im Zweifel ist die Duplikation die billigere Fehlentscheidung. Sie kostet Aufmerksamkeit, die falsche Zusammenführung kostet eine Ausnahmebehandlung. Der erste Punkt ist der Kernfehler: Ähnlichkeit im Code für fachliche Gleichheit zu halten.
6:07 Der dritte beschreibt, was in der Praxis daraus wird — man führt zusammen, merkt die Unterschiede, und holt sie über einen Schalter wieder herein. Am Ende steht eine Funktion mit einem Wahrheitswert im Namen, die zwei Dinge tut. Das ist schlechter als die ursprüngliche Duplikation. Und der vierte ist die organisatorische Konsequenz: Halten Sie die Entscheidung fest, sonst schlägt der nächste Lauf dieselbe Zusammenführung wieder vor, und jemand stimmt zu.
Seiteneffekte isolieren und Zustand zurückdrängen
6:33 Jetzt der lohnendste Umbau, den es im Bestand gibt. Er behebt nicht nur ein Strukturproblem — er ist meistens die Voraussetzung dafür, dass sich überhaupt etwas testen lässt. Sie kennen diese Funktion: Sie rechnet etwas aus, schreibt das Ergebnis in die Datenbank, verschickt eine Nachricht und gibt nebenbei noch einen Wert zurück. Vier Dinge in einem.
6:54 Das ist der häufigste Grund, warum sich Bestandscode nicht testen lässt — Sie können die Berechnung nicht prüfen, ohne die Datenbank hochzufahren und eine Mail zu verschicken. Das Bild dazu: eine Küche, in der gekocht und gleichzeitig ausgeliefert wird. Sie können das Rezept nicht verkosten, ohne dass ein Bote losfährt.
7:13 Der rote Faden ist: das fachlich Interessante herauslösen und die Wirkung nach außen schieben. Schritt zwei ist der Kern — eine Funktion, die Eingaben nimmt und ein Ergebnis liefert, sonst nichts. Danach ist der fachlich interessante Teil ohne jede Vorrichtung testbar: keine Datenbank, kein Mailversand, keine Uhr. Für das Fahrtenbuch heißt das konkret, dass die Steuerlogik prüfbar wird.
7:35 Schritt fünf dehnt dasselbe Prinzip auf gemeinsamen Zustand aus, und die Fußzeile nennt die häufigste Überraschung dabei: Sobald die Verbindungen sichtbar sind, stellt sich meist heraus, dass die Hälfte gar nicht gebraucht wird. Warum ist gemeinsamer Zustand so unangenehm? Weil er eine Verbindung herstellt, die man nicht sieht.
7:54 Zwei Codeteile, die nichts miteinander zu tun haben, sind über eine Variable gekoppelt — und Sie merken das erst, wenn eine Änderung an der einen Stelle die andere kaputt macht. Der dritte Punkt betrifft direkt Ihr Testnetz: Solcher Zustand macht Tests voneinander abhängig, sodass sie je nach Reihenfolge rot oder grün sind.
8:13 Das sind die sporadisch fehlschlagenden Tests aus Modul eins — die, denen bald niemand mehr glaubt.
Toten Code sicher erkennen
8:19 Jetzt der Umbau, der sich am besten anfühlt und die höchste Irrtumsquote hat. Code zu löschen ist befreiend. Es ist auch die Änderung, bei der ein Fehler am teuersten wird. Die Aussage „wird nicht verwendet“ beruht auf einer Suche — und wir haben in Modul drei gesehen, dass eine Suche dynamische Aufrufe nicht findet. Ein Agent gewinnt diese Aussage durch Lesen und meldet sie trotzdem als Tatsache. Bei einem System mit Konfiguration, Reflexion oder Ereignismechanismen ist das Risiko erheblich.
8:49 Und der Schaden hat eine unangenehme Eigenschaft: Er zeigt sich oft erst Monate später, wenn der jährliche Lauf ansteht, der diesen einen Pfad benutzt hat. Zu diesem Zeitpunkt denkt niemand mehr an Ihre Löschung. Die eigentliche Aussage dieses Vorgehens steht in Schritt zwei und drei — und ja, sie ist unbequem. Sie bauen eine Protokollierung ein, lassen sie in der Produktion mitlaufen und entscheiden erst danach. Das dauert Wochen.
9:15 Es ist auch die einzige Methode, die bei einem produktiven System wirklich trägt, weil sie eine Beobachtung liefert statt einer Analyse. Schritt eins ist der billige Vorfilter: Suchen Sie über den Quelltext hinaus — Konfiguration, Datenbank, Skripte, Nachbarsysteme. Und Schritt fünf ist Hygiene: Löschungen bekommen einen eigenen, klar benannten Commit, damit man sie zurücknehmen kann.
9:38 Der vierte Punkt ist der, an den man selten denkt und der die typische Fehlerquelle in der Praxis ist: Sie beobachten zwei Wochen, sehen keinen Aufruf und löschen. Der betreffende Pfad läuft aber einmal im Jahr zum Jahresabschluss. Die Beobachtungsdauer muss zum fachlichen Rhythmus passen — beim Fahrtenbuch heißt das mindestens über einen Monatswechsel, für manche Pfade über einen Jahreswechsel.
10:00 Der zweite Punkt ist praktisch: Löschungen einzeln committen, nie gebündelt. Wenn drei Wochen später etwas fehlt, wollen Sie genau eine Löschung zurücknehmen können.
Werkzeug-Refactoring gegen generative Änderung
10:10 Kommen wir zur Arbeitsteilung. Es gibt einen wichtigen Unterschied zwischen einer Umbenennung durch die Entwicklungsumgebung und derselben Umbenennung durch ein Sprachmodell — und er ist grundsätzlicher Natur. Das Werkzeug arbeitet auf dem Syntaxbaum. Es weiß, was ein Bezeichner ist, welche Vorkommen dazugehören und welche nur zufällig gleich heißen — und es ändert genau die richtigen.
10:32 Das Ergebnis ist deterministisch: zweimal ausgeführt, zweimal dasselbe. Das Modell arbeitet auf Text. Es tut meistens dasselbe und gelegentlich etwas anderes. „Meistens“ ist bei einer mechanischen Operation kein gutes Kriterium — Sie müssen dann nämlich jedes Ergebnis prüfen, und damit haben Sie die Zeitersparnis wieder verloren.
10:53 Die Logik dieser Tabelle ist einfach: Oben steht, was mechanisch entscheidbar ist, unten, was Urteilsvermögen verlangt. Umbenennen, Extrahieren, Signaturen ändern — dafür gibt es eine richtige Antwort, und das Werkzeug findet sie vollständig. Welcher Name der richtige ist, wo die Grenze einer herauszulösenden Funktion sinnvoll liegt, ob zwei Duplikate dieselbe Regel sind — dafür gibt es keine mechanische Antwort, und genau da ist ein Agent stark.
11:19 Die Fußzeile nennt die typischen Fehler der generativen Variante: ein Vorkommen übersehen, eine gleichnamige Variable mitgefasst. Beides fällt beim Überfliegen nicht auf. Der erste Punkt ist der häufigste, und er ist verständlich: Es fühlt sich flüssiger an, alles im Gespräch zu erledigen, als zwischen Chat und Entwicklungsumgebung zu wechseln.
11:40 Diese Bequemlichkeit bezahlen Sie mit Prüfaufwand. Der zweite Punkt ist die Gegenrichtung, die auch vorkommt: Man bedient nur noch Werkzeuge und nutzt den Agenten nicht für das, was er wirklich gut kann — beurteilen. Und der vierte ist banal: Viele Teams haben die Werkzeugunterstützung für ihre Sprache gar nicht eingerichtet. Das lohnt sich vor jedem Modernisierungsvorhaben.
Ein Refactoring pro Schritt
12:01 Zum Abschluss die Regel, an der alles in diesem Modul hängt. Sie klingt nach Prinzipientreue und ist in Wahrheit eine rein praktische Überlegung. Ein Umbau, dann Tests, dann Diff, dann Commit. Nicht zwei Umbauten, weil sie zusammenpassen. Nicht ein Umbau plus die naheliegende kleine Verhaltensverbesserung — das wäre auch die Vermischung aus Modul eins.
12:23 Der Grund ist nicht Dogmatismus, sondern Diagnosefähigkeit: Wenn nach einem Schritt ein Test bricht, kennen Sie die Ursache sofort, denn Sie haben genau eine Sache getan. Das ist der ganze Gewinn — und er ist größer, als er klingt. Der Vergleich zeigt, was auf dem Spiel steht. Bei einem Refactoring pro Schritt ist die Ursache eines roten Tests in Sekunden gefunden — Sie schauen sich die eine Änderung an.
12:48 Bei fünf vermischten Schritten beginnt eine Suche, die häufig länger dauert als der Umbau selbst. Und dann passiert meistens das, was in der Fußzeile steht: Es wird alles verworfen, samt der vier Schritte, die völlig in Ordnung waren. Das ist der eigentliche Verlust — nicht der eine fehlerhafte Schritt, sondern die vier guten, die mit untergehen.
13:08 Warum muss diese Regel ausdrücklich in den Auftrag? Weil ein Agent von sich aus das Gegenteil tut, und zwar aus nachvollziehbaren Gründen. Er sieht den Zusammenhang zwischen den Änderungen und hat keinen Anlass, künstlich zu vereinzeln — die Vereinzelung hat für ihn keinen Nutzen. Und jeder zusätzliche Schritt kostet ihn nichts; der Preis fällt beim Prüfenden an, und den erlebt er nicht. Deshalb gehört die Schrittgröße in den Auftrag, nicht in die Hoffnung.
13:34 Als schöner Nebeneffekt entsteht dabei eine Commit-Kette, die den Umbau besser dokumentiert als jeder nachträgliche Text.
Übung: Befunde priorisieren statt abarbeiten
13:41 Die Übung dreht die naheliegende Erwartung um. Sie bekommen einen Katalog von Auffälligkeiten — und die Aufgabe ist ausdrücklich, ihn nicht abzuarbeiten. Ein Agent liefert Ihnen für ein Modul des Fahrtenbuchs mühelos vierzig Befunde. Die Liste sieht aus wie ein Arbeitsvorrat, und genau diese Wirkung ist die Falle — sie ist konkret, sortiert und macht Lust aufs Abhaken.
14:04 Ihre Aufgabe ist die Bewertung: Steht hier Änderungsdruck an? Ist die Stelle abgesichert? Wie riskant wäre der Umbau? Drei setzen Sie um, sauber, mit Testlauf und Commit nach jedem Schritt. Der Rest bleibt liegen — begründet. Diese Begründung ist der eigentliche Prüfstein. Achten Sie beim Umbauen in Schritt vier wirklich auf die Disziplin: ein Refactoring, Testlauf, Diff, Commit.
14:28 Sie werden merken, dass die Versuchung groß ist, zwei Dinge zusammenzuziehen, weil sie so nah beieinanderliegen. Und Schritt fünf ist der, den Sie mitnehmen sollten. Ein Katalog mit vierzig Befunden, von dem drei umgesetzt werden, ist ein gutes Ergebnis — nicht etwa ein schlechtes. Wenn Sie das im eigenen Team vertreten können, haben Sie den Kern dieses Moduls verstanden.
14:50 Im nächsten Modul geht es um die Umbauten, für die diese kleinen Schritte nicht ausreichen.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →