Code Refactoring

Code-Refactoring ist ein direkter Versuch, Code zu verbessern, ohne neue Module oder Funktionen zu erstellen, und führt so zu benutzerfreundlicherem, saubererem und lesbarerem Code.

Jedes Mal, wenn wir Code ändern, ohne ihn umzugestalten, verschlimmert sich die Fäulnis und breitet sich aus. Codefäule frustriert uns, kostet uns Zeit und verkürzt die Lebensdauer nützlicher Systeme übermäßig. In einem agilen Kontext kann es den Unterschied zwischen der Einhaltung oder Nichteinhaltung einer Iterationsfrist ausmachen.

Das Refactoring von Code verhindert rücksichtslos Fäulnis und sorgt dafür, dass der Code einfach zu warten und zu erweitern ist. Diese Erweiterbarkeit ist der Grund für das Refactoring und der Maßstab für seinen Erfolg. Beachten Sie jedoch, dass es nur „safe„Um den Code so umfassend umzugestalten, wenn wir über umfangreiche Unit-Test-Suites verfügen, wie wir sie erhalten, wenn wir zuerst testen. Wenn wir diese Tests nicht nach jedem kleinen Schritt einer Umgestaltung durchführen können, laufen wir Gefahr, Fehler einzuführen. Wenn Sie eine echte testgetriebene Entwicklung (TDD) durchführen, bei der sich das Design kontinuierlich weiterentwickelt, haben Sie keine Wahl zwischen regelmäßigem Refactoring, da Sie das Design auf diese Weise weiterentwickeln.

Code-Hygiene

Eine beliebte Metapher für Refactoring ist das Reinigen der Küche während des Kochens. In jeder Küche, in der täglich mehrere komplexe Mahlzeiten für mehr als eine Handvoll Personen zubereitet werden, werden Sie normalerweise feststellen, dass ständig gereinigt und neu geordnet wird. Jemand ist dafür verantwortlich, das Geschirr, die Töpfe, die Küche selbst, die Lebensmittel und den Kühlschrank von Moment zu Moment sauber und ordentlich zu halten. Ohne dies würde das kontinuierliche Kochen schnell zusammenbrechen. In Ihrem eigenen Haushalt können Sie nicht unerhebliche Auswirkungen feststellen, wenn Sie auch nur geringfügige Änderungen am Gericht aufschieben: Haben Sie jemals versucht, den durch getrocknete Kakao-Crispies gebildeten Dreck aus einer Schüssel zu kratzen? Eine verpasste Gelegenheit, zwei Sekunden lang zu spülen, kann zu zehn Minuten aggressivem Kratzen werden.

Spezifische „Refactorings“

Refactorings sind das Gegenteil davon, endlos am Code herumzubasteln; sie sind präzise und endlich. Martin Fowlers endgültiges Werk buchen zu diesem Thema beschreibt 72 spezifische „Refactorings“ namentlich (z. B. „Methode extrahieren“, die einen Codeblock aus einer Methode extrahiert und eine neue Methode dafür erstellt). Bei jedem Refactoring wird ein Codeabschnitt (ein Block, eine Methode, eine Klasse) von einem von 22 bekannten „stinkenden“ Zuständen in einen optimaleren Zustand umgewandelt. Es braucht eine Weile, um zu lernen, Refactoring-Chancen zu erkennen und Refactorings richtig umzusetzen.

Refactoring zu Mustern

Refactoring findet nicht nur auf niedrigen Codeebenen statt. In seinem jüngsten Buch Refactoring zu MusternJoshua Kerievsky argumentiert gekonnt, dass Refactoring die Technik ist, die wir verwenden sollten, um „Gang of Four“-Entwurfsmuster in unseren Code einzuführen. Er argumentiert, dass Muster oft überstrapaziert und oft zu früh in Systeme eingeführt werden. Er folgt Fowlers ursprünglichem Format, bestimmte „Refactorings“ anzuzeigen und zu benennen, Rezepte, um Ihren Code von Punkt A nach Punkt B zu bringen. Kerievskys Refactorings sind im Allgemeinen auf einem höheren Niveau als die von Fowler und verwenden Fowlers Refactorings oft als Bausteine. Kerievsky stellt außerdem das Konzept des Refactorings „in Richtung“ eines Musters vor und beschreibt, wie viele Entwurfsmuster mehrere unterschiedliche Implementierungen oder Implementierungstiefen haben. Manchmal brauchen Sie mehr Muster als zu anderen Zeiten, und dieses Buch zeigt Ihnen genau, wie Sie einen Teil oder den gesamten Weg dorthin schaffen.

Der Ablauf des Refactorings

In einem Test-First-Kontext hat das Refactoring den gleichen Ablauf wie jede andere Codeänderung. Sie haben Ihre automatisierten Tests. Sie beginnen mit der Umgestaltung, indem Sie die kleinste mögliche diskrete Änderung vornehmen, die kompiliert, ausgeführt und funktioniert. Wo immer möglich, nehmen Sie solche Änderungen vor, indem Sie parallel dazu den vorhandenen Code ergänzen. Sie führen die Tests durch. Anschließend nehmen Sie die nächste kleine diskrete Änderung vor und führen die Tests erneut durch. Wenn das Refactoring erfolgt ist und alle Tests sauber verlaufen, gehen Sie zurück und entfernen den alten, stinkenden Parallelcode. Sobald die Tests danach sauber verlaufen, sind Sie fertig.

Refactoring-Automatisierung in IDEs

Refactoring lässt sich viel, viel einfacher automatisch durchführen als manuell. Glücklicherweise integrieren immer mehr integrierte Entwicklungsumgebungen (IDEs) automatisierte Refactoring-Unterstützung. Eine beliebte IDE für Java ist beispielsweise Eklipse, was immer mehr Auto-Refactorings beinhaltet. Ein weiterer Favorit ist IntelliJ IDEA, was in der Vergangenheit sogar noch mehr Refactorings beinhaltete. In der .NET-Welt gibt es mindestens zwei Refactoring-Tool-Plugins für Visual Studio 2003, und uns wurde gesagt, dass zukünftige Versionen von Visual Studio über integrierte Refactoring-Unterstützung verfügen werden.

Um Code in Eclipse oder IDEA umzugestalten, wählen Sie den Code aus, den Sie umgestalten möchten, rufen aus einem Menü die spezifische Umgestaltung auf, die Sie benötigen, und die IDE erledigt den Rest der harten Arbeit. Sie werden in entsprechenden Dialogfeldern zur Eingabe neuer Namen für Dinge, die benannt werden müssen, und zu ähnlichen Eingaben aufgefordert. Anschließend können Sie Ihre Tests sofort erneut ausführen, um sicherzustellen, dass durch die Änderung nichts beschädigt wurde. Wenn etwas kaputt ist, können Sie die Umgestaltung leicht rückgängig machen und die Sache untersuchen.