Ich habe gerade einen Code überarbeitet, der in einem anderen Abschnitt der Klasse war, an der ich gerade arbeitete, weil es eine Reihe von geschachtelten Bedingungsoperatoren (? :) war, die durch eine ziemlich einfache switch-Anweisung (C #) deutlicher gemacht wurden.
Wann werden Sie Code berühren, der nicht direkt mit dem übereinstimmt, woran Sie arbeiten, um ihn klarer zu machen?
Ich habe einmal refactoring und stieß auf etwas wie diesen Code:
%Vor%Resharper wies darauf hin, dass der .ToString () redundant war, also nahm ich ihn heraus. Leider endete damit der Code. Immer wenn MySessionVar null war, verursachte es nicht die NullReferenceException, auf die der Code angewiesen war, um sie auf den catch-Block zu stoßen. Ich weiß, das war ein trauriger Code. Aber ich habe daraus eine gute Lektion gelernt. Gehen Sie nicht schnell durch alten Code, der sich auf ein Tool stützt, das Ihnen beim Refactoring hilft - denken Sie es selbst durch.
Ich habe es am Ende wie folgt refactoring:
%Vor%Update: Da dieser Post upgestimmt wird und technisch keine Antwort auf die Frage enthält, dachte ich mir, ich sollte die Frage eigentlich beantworten. (Ok, es stört mich so sehr, dass ich davon träumte.)
Persönlich stelle ich mir vor dem Refactoring ein paar Fragen.
1) Wird das System von der Quelle kontrolliert? Wenn ja, dann gehen Sie vor und refactor, weil Sie immer zurückrollen können, wenn etwas bricht.
2) Gibt es Komponententests für die Funktionalität, die ich verändere? Wenn ja, großartig! Refaktor. Die Gefahr besteht hier darin, dass die Existenz von Unit-Tests nicht die Genauigkeit und den Umfang der Unit-Tests anzeigt. Gute Komponententests sollten alle brechenden Änderungen aufgreifen.
3) Verstehe ich den Code, den ich umgestalte, gründlich? Wenn es keine Quellcodeverwaltung und keine Tests gibt und ich den Code, den ich ändere, nicht wirklich verstehe, ist das eine rote Flagge. Ich müsste vor dem Refactoring mit dem Code vertrauter werden.
Im Fall # 3 würde ich wahrscheinlich die Zeit aufwenden, um tatsächlich den gesamten Code zu verfolgen, der gerade die Methode verwendet, die ich refaktoriere. Abhängig vom Umfang des Codes könnte dies einfach oder unmöglich sein (zB wenn es sich um eine öffentliche API handelt). Wenn es darum geht, eine öffentliche API zu sein, dann müssen Sie wirklich die ursprüngliche Absicht des Codes aus einer geschäftlichen Perspektive verstehen.
Ich refaktoriere es nur, wenn Tests bereits vorhanden sind. Wenn nicht, ist es in der Regel nicht meine Zeit wert, Tests für und Refactor für vermutlich funktionierenden Code zu schreiben.
Dies ist eine kleine, kleine Antipattern, aber es irritiert mich so, wenn ich es finde, lösche ich es sofort . In C (oder C ++ oder Java)
%Vor%wird
%Vor%Im Schema
%Vor%wird
%Vor%und in ML
%Vor%wird
%Vor%Ich sehe diese Antipattern fast ausschließlich in Code von Studenten geschrieben . Ich bin definitiv das nicht erfunden !!
Immer wenn ich darauf stoße und ich denke nicht, dass das Ändern Probleme verursachen wird (z. B. kann ich es genug verstehen, dass ich weiß, was es tut. Zum Beispiel ist das Voodoo-Niveau niedrig).
Ich bemühe mich nur, es zu ändern, wenn ich einen anderen Grund habe, den Code zu modifizieren.
Wie weit ich bereit bin, es zu nehmen, hängt davon ab, wie zuversichtlich ich bin, dass ich nichts kaputt machen werde und wie umfangreich meine eigenen Änderungen am Code sein werden.
Dies ist eine großartige Situation, um die Vorteile von Komponententests aufzuzeigen.
Wenn Komponententests vorhanden sind, können Entwickler merkwürdig geschriebenen Code mutig und aggressiv umgestalten, auf den sie stoßen könnten. Wenn es die Komponententests besteht und Sie die Lesbarkeit erhöht haben, dann haben Sie Ihre gute Tat für den Tag getan und können weitermachen.
Ohne Komponententests stellt die Vereinfachung von komplexem Code, der mit Voodoo gefüllt ist, ein großes Risiko dar, den Code zu durchbrechen und nicht einmal zu wissen, dass Sie einen neuen Bug eingeführt haben! Die meisten Entwickler werden also vorsichtig vorgehen und weitermachen.
Beim einfachen Refactoring versuche ich tief verschachtelte Kontrollstrukturen und wirklich lange Funktionen (mehr als einen Bildschirm Text) zu bereinigen. Es ist jedoch keine gute Idee, Code ohne guten Grund zu refaktorieren (besonders in einem großen Team von Entwicklern). Im Allgemeinen, wenn das Refactoring keine große Verbesserung im Code macht oder eine ungeheuerliche Sünde behebt, versuche ich, gut genug in Ruhe zu lassen.
Refactoring per-say nicht, aber nur als eine Frage des allgemeinen Housekeepings mache ich diese Sachen normalerweise, wenn ich anfange, an einem Modul zu arbeiten:
Mehr als (wahrscheinlich) drei oder vier Zeilen doppelten Codes immer lassen mich über Refactoring nachdenken. Außerdem tendiere ich dazu, Code um eine Menge zu bewegen, indem ich den Code, den ich vorhergesagt habe, häufiger an einen anderen Ort extrahiere - eine Klasse mit einem eigenen klar definierten Zweck und Verantwortlichkeiten oder eine statische Methode einer statischen Klasse (normalerweise in mein Utils. * Namensraum).
Aber um Ihre Frage zu beantworten, ja, es gibt viele Fälle, in denen die Kürzung des Codes nicht notwendigerweise bedeutet, dass er gut strukturiert und lesbar ist. Das Verwenden des ?? -Operators in C # ist ein anderes Beispiel. Was Sie auch denken müssen, sind die neuen Funktionen in Ihrer Sprache der Wahl - z. LINQ kann verwendet werden, um einige Dinge auf eine sehr elegante Art und Weise zu tun, kann aber auch eine sehr einfache Sache sehr unlesbar und komplex machen. Sie müssen diese zwei Dinge sehr sorgfältig abwägen, am Ende läuft alles auf Ihren persönlichen Geschmack und vor allem Erfahrung hinaus.
Nun, das ist eine andere "es kommt darauf an" Antwort, aber ich fürchte, es muss sein.
Ich brich fast immer zwei ähnliche Bedingungen in einen Schalter ... am häufigsten in Bezug auf Enums. Ich werde eine Rückkehr abkürzen, anstatt eine lange Aussage.
ex:
%Vor%wird zu:
%Vor%Das frühzeitige Ausbrechen reduziert zusätzliche Gedankenstriche und reduziert lange Code-Bits ... auch als allgemeine Regel mag ich keine Methoden mit mehr als 10-15 Zeilen Code. Ich mag Methoden, die einen einzigartigen Zweck haben, selbst wenn sie intern mehr private Methoden erstellen.
Normalerweise refobiere ich den Code nicht, wenn ich ihn nur durchsuche und nicht aktiv daran arbeite.
Aber manchmal weist ReSharper auf ein paar Dinge hin, denen ich einfach nicht widerstehen kann. :)
Ich tendiere dazu, sehr lange Funktionen und Methoden umzuformen, wenn ich die Menge der Ein- und Ausgänge zu einem Block verstehe.
Dies hilft Lesbarkeit kein Ende.
Ich würde nur den Code umgestalten, auf den ich stoße und an dem ich nach den folgenden Schritten nicht aktiv arbeite:
Das Refactoring dafür ist eine der Wurzeln allen Übels. Bitte tu es nie. (Unit-Tests mildern dies etwas).
Ist ein großer Teil des auskommentierten Codes ein Antipattern? Während ich nicht speziell Code (es ist Kommentare) sehe ich eine Menge von dieser Art von Verhalten mit Menschen, die nicht verstehen, wie die Quellcodeverwaltung zu verwenden, und die den alten Code für später behalten möchten, so dass sie leichter zurückgehen können, wenn Ein Fehler wurde eingeführt. Immer wenn ich riesige Codeausschnitte sehe, die auskommentiert sind, entferne ich sie fast immer komplett.
Ich versuche, basierend auf folgenden Faktoren umzuformen:
Und manchmal, wenn ich genug Zeit habe, refactor um zu lernen. Wie in, weiß ich, dass meine Änderung den Code brechen kann, aber ich weiß nicht wo und wie. Also ändere ich es trotzdem, um herauszufinden, wo es bricht und warum. Auf diese Weise lerne ich mehr über den Code.
Meine Domain war eine mobile Software (Mobiltelefone), in der sich der Großteil des Codes auf meinem PC befindet und andere nicht beeinträchtigt. Da ich auch das CI-Build-System für meine Firma verwalte, kann ich einen kompletten Produkt-Build (für alle Telefone) auf dem refaktorierten Code ausführen, um sicherzustellen, dass nichts anderes kaputt geht. Aber das ist mein persönlicher Luxus, den du vielleicht nicht hast.
Ich tendiere dazu, globale Konstanten und Aufzählungen um ein Vielfaches zu refaktorieren, wenn sie als ein geringes Refaktorrisiko angesehen werden können. Vielleicht ist es nur so, aber etwas wie eine ClientAccountStatus-Enumeration sollte in oder nahe der ClientAccount-Klasse sein, anstatt in einer GlobalConstAndEnum-Klasse zu sein.
Löschung / Aktualisierung von Kommentaren, die eindeutig falsch oder eindeutig sinnlos sind.
Entfernen sie ist:
Es geht um das einzige 100% risikofreie Refactoring, das ich kenne.
Beachten Sie, dass dies in strukturierten Kommentaren wie Javadoc-Kommentaren eine andere Sache ist. Diese zu ändern ist nicht risikofrei, da sie sehr wahrscheinlich wahrscheinlich sind, die repariert / entfernt werden, aber nicht dead, bestimmte garantierte Fixes, wie standardmäßige falsche Code-Kommentare.
Tags und Links refactoring anti-patterns