Wann umgestalten?

32

Ich habe den größten Teil von Fowlers Refactoring-Buch gelesen und in meiner Vergangenheit viele große und kleine Anwendungen überarbeitet.

Eines der schwierigeren Dinge, die ich zu lehren finde, ist "wann" umzugestalten. Ich tendiere dazu, dies auf der Grundlage eines Bauchgefühls zu tun, das mir in der Vergangenheit bemerkenswert gut gedient hat. Wenn man jedoch mit Leuten darüber diskutiert, ob ein Teil des Codes jetzt alleine gelassen oder überarbeitet werden soll, ist es schwierig, den "Darmcheck" zu bestehen.

Ich bin der Meinung, dass es strengere Ansätze geben sollte, bin mir aber nicht sicher, was sie sind.

Ich verstehe "Code-Gerüche", Rot-Grün-Refaktor und andere Gedanken, aber ich habe oft das Gefühl, dass der beste Zeitpunkt für die Refaktorisierung nicht das erste Mal ist, wenn Sie den Code schreiben, sondern das zweite oder dritte Mal, wenn Sie den Code verwenden und erkennen dass es sich tatsächlich um ein Problem handelt und tatsächlich verwendet wird.

Hortitude
quelle
2
Im Wesentlichen fragen Sie das Gleiche: programmers.stackexchange.com/questions/6268/… . Mit der Ausnahme, dass Ihre Handlungsschwelle niedriger ist, da die Kosten und das Risiko niedriger sind, oder?
S.Lott

Antworten:

22

Refactor, wenn die Kosten für das Refactoring geringer sind als die Kosten für das Nicht- Refactoring.

Messen Sie "Kosten", wie Sie können. Ist der Code beispielsweise so schlecht implementiert, dass die Behebung trivialer Fehler Stunden oder Tage kostet? Können Sie durch Refactoring mehr Kunden gewinnen oder die Kapazität erhöhen oder die Leistung verbessern und so Ihre bestehenden Kunden zufriedener machen?

Bryan Oakley
quelle
Kurzform und perfekt
ZJR
8
Mit anderen Worten: "Es lohnt sich zu refaktorieren, wenn es sich lohnt zu refaktorieren". Duh. Nun, es ist keine wirkliche Antwort, oder :) Measure "cost" however you can.- OK, wie? Ist das nicht der Kern der Frage? Welche Zeitperspektive sollte angewendet werden, wenn diese Kosten gemessen werden?
Konrad Morawski
2
@ Morawski: nein, das ist eine falsche umschreibung. Ich sagte, dass es sich lohnt, ein Refactoring durchzuführen, wenn der durch das Refactoring erhaltene Wert höher ist als die Kosten für das Refactoring. Das ist nicht dasselbe wie zu sagen "es lohnt sich zu refaktorieren, wenn es sich lohnt zu refaktorieren". Berechnen Sie die Kosten für das Refactoring. Berechnen Sie die Kosten für das Nicht-Refactoring. Welches ist größer?
Bryan Oakley
@BryanOakley: Das Problem ist, dass Sie diese Kosten nicht "berechnen" können. Sie können sie bestenfalls abschätzen, was bei den Kosten für das Nicht-Refactoring sehr schwierig ist . Welchen Wartungskosten-Multiplikator wenden Sie auf die nicht überarbeitete Version gegenüber der überarbeiteten Version an? Woher wissen Sie, ob der betreffende Code überhaupt gewartet oder geändert werden muss? Wie schätzen Sie die Anzahl der Fehler ein, die dadurch verursacht werden? Letztendlich nehmen wir alle diese Art von Schätzungen unbewusst als Teil unseres Entscheidungsprozesses vor, wenn wir über ein Refactoring nachdenken, aber es ist keine Genauigkeit zu erwarten.
Guillaume31
1
@ ian31: Richtig, Sie können keine Werte berechnen, und das Beste, was Sie tun können, ist zu schätzen. Dies ist jedoch die einzig gültige Methode, um zu entscheiden, ob eine Umgestaltung durchgeführt werden soll oder nicht, vorausgesetzt, Sie haben nur begrenzte Zeit und Ressourcen. Sie müssen entscheiden, ob sich der Refaktor lohnt. Wie Sie "Wert" definieren, ist eine sehr ungenaue Wissenschaft. Der Punkt ist, dass Sie nicht aus dem Bauch heraus umgestalten sollten - es sollte einen guten Grund für das Umgestalten geben, außer "Ich möchte, dass der Code hübscher ist".
Bryan Oakley
12

  1. Beträgt die zyklomatische Komplexität der Funktion weniger als 5?
  2. Haben Sie die Komplexität der Zyklomatik vollständig verstanden, ohne diesem Link zu folgen?
  3. Haben Sie einen automatisierten Test oder einen dokumentierten Testfall für jeden Pfad durch die Funktion?
  4. Bestehen alle vorhandenen Testfälle?
  5. Können Sie mir die Funktion und alle Randfälle in weniger als 1 Minute erklären?
  6. Wenn nicht, wie wäre es mit 5 Minuten?
  7. 10 Minuten?
  8. Befinden sich weniger als 100 Codezeilen in der Funktion (einschließlich Kommentaren)?
  9. Können Sie zwei andere Entwickler finden, die zustimmen, dass dieser Code nur durch visuelle Inspektion fehlerfrei ist?
  10. Wird diese Funktion nur an einer Stelle verwendet?
  11. Erfüllt die Funktion ihre Leistungsziele (Zeit / Speicher / CPU)?

Wertung

Addieren Sie die obigen "Nein" -Antworten:

  • 0-1 - Warum sollten Sie überhaupt darüber nachdenken, dies umzugestalten? Sie möchten wahrscheinlich nur Variablen umbenennen, weil Ihnen die Namenskonvention des vorherigen Entwicklers nicht gefällt
  • 2-5 - Das muss vielleicht ein wenig geändert werden, aber ich würde eine Produktionsfreigabe für etwas in diesem Bereich nicht aufhalten
  • 6-8 - OK, wir müssen das wahrscheinlich reparieren ... Es ist wahrscheinlich, dass wir dies weiterhin wiederholen werden und / oder wir wissen nicht wirklich, was es tut. Immer noch auf dem Zaun, aber es ist sehr verdächtig
  • 9+ - Dies ist ein erstklassiger Kandidat für das Refactoring. (Hinweis: Das Schreiben von Testfällen ist eine Form des Refactorings.)

http://mikemainguy.blogspot.com/2013/05/when-to-refactor-code.html

Mainguy
quelle
4
# 2 klingt sehr snobistisch und ist eigentlich für die Auswertung von Code unbrauchbar . # 3 & # 4 Nicht jedes Unternehmen verwendet Unit-Tests. # 8 Vermeiden Sie Kommentare, wo immer dies möglich ist, und 100 Zeilen sind zu hoch. Ich habe 1 großen Breitbild-Monitor im Hochformat und kann kaum die gesamte Funktion auf einmal sehen. Wenn es sich um mehr als 15 Zeilen tatsächlichen Codes handelt, sollte es bereits einen soliden Grund geben, warum Sie dies so beibehalten. Es ist eine nette, praktische Methode, eine Checkliste zu haben, aber hier werden zu viele Punkte nur erfunden oder es werden zufällige Werte verwendet, ohne dass ein Grund dahinter steckt.
R. Schmitz
8

Wenn Ihnen Ihr Bauch sagt, dass Sie wahrscheinlich etwas überarbeiten sollten, ist es wahrscheinlich, dass Ihre Instinkte Ihnen etwas zu spät sagen, dass Sie etwas Wichtiges zu lange aufgeschoben haben.

Ich verstehe "Code-Gerüche", Rot-Grün-Refaktor und andere Gedanken, aber ich habe oft das Gefühl, dass der beste Zeitpunkt für die Refaktorisierung nicht das erste Mal ist, wenn Sie den Code schreiben, sondern das zweite oder dritte Mal, wenn Sie den Code verwenden und erkennen dass es sich tatsächlich um ein Problem handelt und tatsächlich verwendet wird.

Das Refactoring umfasst effektiv zwei Ebenen. Das erste Problem sind die offensichtlichen Probleme, die beim ersten Codieren auftreten. Dies sind die kleinen Optimierungen, die Sie im Vorfeld nur sehr wenig kosten. Halten Sie Ihre Methoden und Klassen klein und halten Sie sich an DRY und SRP. Dann haben Sie die zusätzliche Phase, in der Sie sich mit größeren Fehlern in Ihrem Design befassen müssen, die möglicherweise erst dann sofort sichtbar werden, wenn Ihr Code einige Kilometer darunter liegt. Es ist diese zweite Ebene, über die Sie sprechen, und um sicherzustellen, dass ein späteres Refactoring nicht zu kostspielig ist, müssen Sie Ihren Code bereits so geschrieben haben, dass der Aufwand, den Sie sich später vorstellen, einfacher und kostengünstiger wird. was bedeutet, dass eine frühe Umgestaltung durchgeführt wird.

Wie Jeff in seiner Antwort erwähnte, ist "Zeit Geld" , insbesondere in Unternehmen, in denen die Arbeitsbelastung hoch und die Risiken noch höher sind. Zeit, die im Vorfeld aufgewendet wurde, um sicherzustellen, dass der Code in seinem bestmöglichen Zustand ist, wird später Zeit gespart, wenn sich herausstellt, dass das, was ein einfaches Refactoring gewesen sein sollte, ein großer Vorgang ist.

Wenn Sie Software schreiben, wird jeder Moment, in dem Sie Ihren Code im Voraus verbessern, Zeit gespart, wenn Sie ihn wirklich brauchen. Je früher Sie umgestalten, desto deutlicher werden Ihre späteren Änderungen. Es ist wie eine Anzahlung in heutigen Dollars gegen zukünftige technische Schulden zu leisten, die morgen in aufgeblasenen Dollars sein werden.

In jedem Fall sollte Refactoring keine Aufgabe sein, die Sie bis zu einer mysteriösen Zukunft verschieben sollten, wenn die Software bereits vollständig und stabil ist, da dies Ihre Risiken später erhöht, wenn die Einsätze viel höher und das Produkt viel schwieriger zu ändern sind. Refactoring sollte ein Teil Ihrer täglichen Aktivitäten sein, und dies ist die Essenz der von Ihnen erwähnten Red-Green-Refactor-Philosophie.

S.Robins
quelle
2

Ich denke, Ihre Frage kann von jedem Entwickler und sogar dem für die Programmierung zuständigen Management unterschiedlich beantwortet werden.

Persönlich bevorzuge ich, wenn ich etwas Neues lerne oder meine Best Practices verbessere, den Code, den ich kann, umzugestalten. Ich halte meinen Code gerne auf dem neuesten Stand, sobald ich weiß, welcher Standard für diese Situation am besten geeignet ist. Ich darf das allerdings, weil es ein kleineres Unternehmen ist, das die gleiche Software für lange Zeiträume verwendet.

In einem größeren Softwareentwicklungsunternehmen, in dem Zeit Geld ist, kann es sein, dass Sie erst dann mit dem Entwerfen beginnen, wenn Sie die von diesem Punkt an erlernten besseren Vorgehensweisen angewendet haben.

Ich bin der Meinung, dass das Unterrichten, wann umgestaltet werden muss, wirklich von der Firma abhängt, in der Sie sich gerade befinden.

Jeff
quelle
2

"Wann umgestalten?"

Kurze Antwort: Jedes Mal, wenn Sie auf Code stoßen, der schlecht riecht oder verbessert werden könnte ( Pfadfinderregel )

In der Praxis passiert Folgendes:

  • Wenn Sie TDD systematisch während des Refactor-Schritts des TDD-Zyklus üben, dh sobald Ihr Test grün ist und bevor Sie mit dem Schreiben eines neuen Tests beginnen.
  • Als Ergebnis einer Codeüberprüfung
  • Bei der Übernahme von Legacy-Code
  • Wenn Sie Code konsumieren, scheint dies umständlich zu sein
  • etc.
guillaume31
quelle
Ich habe das Gefühl, dass dies nur "Sie sollten umgestalten" sagt, ohne auf den schwierigeren Teil zu antworten: "Ich habe das Gefühl, dass es strengere Ansätze geben sollte, aber ich bin nicht sicher, was sie sind."
Hortitude
Ich weiß nicht, was ich sagen soll, außer zu fühlen, was schmerzhaft zu warten ist, nach Code-Gerüchen zu schnüffeln und deine Erfahrung zu nutzen. Ich bezweifle, dass es jemals eine endgültige, etablierte Methode geben wird, die Ihnen sagt, wann und was Sie umgestalten müssen, wenn Sie danach suchen.
Guillaume31
1

Als ich das Refactoring zum ersten Mal lernte, sagte mir mein Mentor: "Mach es zweimal, halte deine Nase. Mach es dreimal. Refactor." (Danke, Josh!) Um genau zu sein, sagte er, wenn Sie im Begriff sind, zum dritten Mal denselben Codeblock (oder sogar ein ähnliches Codemuster) zu schreiben, ist dies die Zeit für eine Umgestaltung. Ich habe das in den letzten 10 Jahren verfolgt und fand, dass es eine hinreichende Faustregel ist.

Die Verwendung von Eclipse oder einer ähnlichen IDE mit starker Refactoring-Unterstützung reduziert den Aufwand für das Refactoring. Die IDE-Unterstützung erhöht die Wahrscheinlichkeit, dass Sie eine Umgestaltung vornehmen, sobald Sie das "dritte Mal" (oder die Notwendigkeit sehen), anstatt dies als zusätzlichen Aufwand zu betrachten.

Auch hier ist TDD eine große Hilfe, da Sie Ihre Tests weiterhin als Refactor ausführen können und wissen, dass Sie nichts kaputt gemacht haben.

Sam Goldberg
quelle
1

Refactoring nach seiner Definition ist ein Prozess. Dies bedeutet, dass Sie nicht danach streben sollten, Zeit für die Durchführung der Rafactoring-Aufgabe zu finden, sondern die ganze Zeit über umgestalten sollten, wenn Sie auf Code stoßen, der besser geschrieben werden könnte.

Persönlich schreibe ich gerne evolutionäre Prototypen und sage es einfacher: Code, der einfach funktioniert, und überarbeite diese, bis sie den erwarteten Codierungsstandards entsprechen. Ein weiteres gutes Beispiel ist das Hinzufügen zusätzlicher Funktionen und das Umgestalten des vorhandenen Codes, um dessen Wiederverwendung zu ermöglichen.

0lukasz0
quelle
1

In meinen 20 Jahren in der Programmierung ist dies die einzige Faustregel, bei der ich tatsächlich Arbeit gesehen habe, an die sich die Leute halten können, und die Manager haben Zeit dafür. (Refactoring ist wie eine Diät: Sicher, "Kalorien rein / Kalorien raus" ist die Formel zum Abnehmen, aber das führt nicht zu einer Diät, die die Leute einhalten werden.) Und so:

Refactor kontinuierlich, während Sie arbeiten. Verwenden Sie Test Driven Development, damit Sie mehrere Rot-Grün-Refaktor- Zyklen im Laufe des Tages haben. Refactor nur die Teile des Codes, die Sie berührt haben.

Sobald Sie sich sicher sind, können Sie von diesem Schema abweichen.

Hundewetter
quelle
1

Ich denke, das hängt von den Anforderungen des Projektbesitzers und desjenigen ab, der für die Qualität des Codes verantwortlich ist. Man kann es einfach nicht alleine entscheiden, wenn das Geld von jemand anderem in Frage kommt.

Aus technischen Gründen gibt es mehrere.

  • Wenn Sie einen Fehler im Code haben, bedeutet dies, dass dieser Ort missverstanden wird und es SEHR wahrscheinlich ist, dass hier weitere Fehler ausgeblendet werden, und es wird mit Sicherheit große Probleme bei jedem Versuch geben, die verbundenen Teile des Codes zu entwickeln. Daher sollte dieser Ort auf mögliche Umgestaltungen überprüft werden.
  • Ein weiterer Grund ist, wenn Sie ein Feature hinzufügen oder ändern und der alte Code für das Ändern / Hinzufügen sehr unpraktisch ist und die späteren Änderungen / Hinzufügungen sehr wahrscheinlich sind. Natürlich sollten Sie die Kosten ausgleichen.
  • Der wahrscheinlich schwerwiegendste Grund ist, dass Sie den Code ändern und er nicht testbar ist.
Gangnus
quelle
Als Scrum-Master hatten wir einen Entwickler, der ständig argumentierte, dass jede Story im Team größer sei als das, was das Team dachte, und erkannte, dass er jeden Code, auf den er stieß, überarbeiten wollte. Daher war eine 3-Punkte-Geschichte für ihn immer eine 8. Dies hat eindeutig die Lieferung von Wert vermasselt. Irgendwie muss also klar sein, wann umgestaltet werden muss und wie die Entscheidung getroffen werden sollte. Nur mein Gedanke aus dieser (und ein paar anderen) Erfahrung.
Curtis Reed