Refactor / Code umschreiben oder fortfahren?

8

Ich habe gerade ein komplexes Stück Code fertiggestellt. Es funktioniert nach Spezifikation, es erfüllt Leistungsanforderungen usw., aber ich bin ein wenig besorgt darüber und überlege, es neu zu schreiben und / oder zu refactoring. Sollte ich dies tun (Zeitaufwand, der sonst für Features aufgewendet werden könnte, die Benutzer tatsächlich bemerken)?

Die Gründe, warum ich Angst vor dem Code habe, sind:

  1. Die Klassenhierarchie ist komplex und nicht offensichtlich
  2. Einige Klassen haben keinen genau definierten Zweck (sie machen eine Reihe von nicht miteinander verwandten Dingen)
  3. Einige Klassen verwenden andere Interna (sie sind als Freundesklassen deklariert), um die Abstraktionsebenen für die Leistung zu umgehen, aber ich glaube, sie brechen die Kapselung, indem Sie dies tun
  4. Einige Klassen verlieren Implementierungsdetails (z. B. habe ich früher eine Map in eine Hash-Map geändert und musste feststellen, dass ich Code in anderen Quelldateien ändern muss, damit die Änderung funktioniert)
  5. Mein Speichermanagement / Pooling-System ist irgendwie klobig und weniger als transparent

Sie sehen aus wie gute Gründe dafür, Code zu überarbeiten und zu säubern, um zukünftige Wartung und Erweiterung zu unterstützen, aber er könnte ziemlich zeitaufwendig sein. Außerdem werde ich niemals mit irgendeinem Code zufrieden sein, den ich schreibe ...

Also, was denkt stackoverflow? Code reinigen oder an Features arbeiten?

    
Dan 14.05.2010, 23:21
quelle

15 Antworten

6

Ich würde argumentieren, dass Sie, wenn Sie das Bedürfnis haben, diesen Code umzuformulieren, ihn noch nicht "abgeschlossen" haben.

Ich denke, es ist viel besser, wenn Sie umgestalten (vorausgesetzt, Sie haben Tests und folgen der Rot-Grün-Refactor-Methode von TDD), aber wenn Sie da sind, gibt es nicht viel Sinn, Ihnen zu sagen, was Sie "sollten" getan haben.

Ich würde Ihnen raten, es zu refaktorisieren. Allerdings würde der Pragmatiker in mir den folgenden Vorbehalt geben - Code wird nie "erledigt", also Timebox dein Refactoring dieses Mal (also gönn dir eine Stunde oder zwei, halte die Tests bestanden und nenne dich dann "erledigt") und dann berührst du den Code jedes Mal, wenn du den Code anfängst, folge der Pfadfinderregel und säubere sie der Code ein wenig jedes Mal, wenn Sie es einchecken. Im Laufe der Zeit werden Sie diesen Code aufräumen - und in Zukunft versuchen, Refactor als Teil des Entwicklungsprozesses, anstatt als eine große Aufgabe zu tun das Ende der Entwicklung.

    
Paddyslacker 14.05.2010, 23:29
quelle
3

Refaktoriere es jetzt.

Da Sie sogar über das Refactoring nachdenken, klingt es, als könnten Sie sich die Zeit dafür nehmen. Wenn Sie es für später verlassen, sind Sie wahrscheinlich mit anderen Dingen beschäftigt und verlieren diese Gelegenheit. Wenn die Zeitpläne knapp werden, können die Kunden verstehen, ob Sie etwas mehr Zeit benötigen, um ein neues Feature fertig zu stellen. Sie sind viel weniger verständnisvoll, wenn Sie ihnen sagen, dass Sie zusätzliche Zeit benötigen, um etwas umzuschreiben, das bereits funktioniert.

    
dbyrne 14.05.2010 23:35
quelle
2

Soweit ich sagen kann, sind Sie ein bisschen perfektionistisch und möchten Ihren Code so sauber wie möglich machen, eine würdige Eigenschaft, aber im Geschäft müssen Sie die Kosten-Nutzen-Analyse Ihres Tuns berücksichtigen. Wenn der Code den Spezifikationen entspricht und es wichtigere Funktionen gibt, notieren Sie, dass Sie den Code umgestalten und weitermachen möchten. Wenn Sie jemals etwas Freizeit haben, können Sie zurückkommen.

    
Serge 14.05.2010 23:30
quelle
2

Wenn dieser Code die QA bereits bestanden hat, sollten Sie ihn vielleicht so wie er ist freigeben und die Code-Schulden akzeptieren. Wenn es Zeit gibt, dafür zu investieren, würde ich die Teile davon auswählen, die am ungeheuerlichsten sind, und versuchen, diese zu umgestalten, zum Beispiel die Umsetzung Ihrer Hashtable-Implementierung. Erstellen Sie andernfalls eine Liste mit Dingen, die Sie verbessern möchten, und arbeiten Sie an den Verbesserungen Ihrer zukünftigen Änderungsanforderungen.

Es ist gut über dich selbst zu wissen, dass du mit dem Code niemals zufrieden bist. Erinnere dich daran, dass du deinen Perfektionismus nicht in die Lage legst, regelmäßig zu veröffentlichen.

    
roufamatic 14.05.2010 23:33
quelle
2

In einem deiner Kommentare hast du gesagt: "Es wird viel Code drauf gebaut." Sie sagen, dass es richtig funktioniert, aber wenn es schlampig ist und auf schlechten Designprinzipien beruht, wird es immer schwieriger werden, irgendetwas im Laufe der Zeit zu ändern. Im Allgemeinen gilt, je wichtiger ein Code ist, desto besser sollte er aussehen. Holen Sie sich das Design richtig, bevor Sie Dinge hinzufügen (im Rahmen des Zumutbaren).

Plus, eines der Hauptziele des Schreibens von Software (meiner Meinung nach) ist es, Komplexität zu verwalten. Wenn Sie es funktioniert haben, haben Sie die Hälfte der Arbeit erledigt. Die andere SEHR wichtige Hälfte des Jobs besteht darin, die Dinge einigermaßen leicht zu verstehen und zu verändern. Ohne das erstellen Sie Software, die nicht gut auf Änderungen reagiert. Und Software muss sich ändern. Oft.

Meine Firma hat eine Software, die sehr schlampig in den Kinderschuhen steckt, und jede kleine Veränderung, die über die Jahre hinzugefügt wurde, wurde schlampig auf die bereits schlampige Basis genagelt. Jetzt ist es an dem Punkt, an dem die Leute nach einfachen Dingen fragen (wie zum Beispiel Mausrad-Unterstützung zum Scrollen), und der Hauptentwickler antwortet mit "Sie wissen nicht, wie viel ich ändern müsste, um das zu tun". Wenn der Code während des Schreibens (oder kurz danach) gereinigt wurde, haben wir dieses Problem nicht.

Wenn Sie jetzt schlampigen, schlecht entworfenen Code haben, wird Sie später in den Hintern beißen. Vor allem, wenn viel anderer Code darüber geschrieben wird.

    
Phil 15.05.2010 00:03
quelle
1

Ist es wahrscheinlich, dass andere den Greueln ausgesetzt werden, die Sie verursacht haben? Wenn ich schrecklichen Code in die Wildnis entlassen habe, tendiere ich dazu, ihn zu säubern, aber wenn ich der Einzige bin, der der Wartung und dem Umgang damit ausgesetzt ist, werde ich es eine Weile schwächen lassen funktioniert gut genug und wenn ich mich ein bisschen darauf setze, könnte ich sogar eine bessere Lösung finden, als ich es gewesen wäre. Ich wurde inspiriert, es sofort zu "reparieren".

IMHO, natürlich.

    
dash-tom-bang 14.05.2010 23:25
quelle
1

"Einige Klassen verlieren Implementierungsdetails (z. B. habe ich früher eine Map in eine Hash-Map geändert und musste feststellen, dass ich Code in anderen Quelldateien ändern muss, damit die Änderung funktioniert)"

Das ist Grund genug, dass es sich im Aufwand lohnt. Per Definition ist es etwas, das Benutzer tatsächlich bemerken.

Einige andere wichtige Dinge zu beachten:

  • Wartbarkeit - Wie einfach wird es sein, alle unvermeidlichen Fehler zu beheben?
  • Testability - Wenn Sie Ihren Code in eine besser testbare Form bringen, ist dies eine großartige Möglichkeit, ihn zu refaktorisieren. Das Hinzufügen von Komponententests bedeutet dann, dass Sie es ändern können und genau wissen, was bricht.
  • Erweiterbarkeit - Denken Sie, dass Sie jemals neue Funktionen hinzufügen müssen?

Es ist wirklich das einzige Mal, dass Sie nicht daran denken sollten, Ihren Code besser zu machen, wenn Sie sicher sind, dass Sie ihn nie wieder anfassen müssen (d. h. fast nie).

    
Cogwheel 14.05.2010 23:26
quelle
1

"Ich habe gerade abgeschlossen ..."

Es klingt so, als würden Sie aktiv Legacy-Code schreiben, was nicht gut ist. Sie haben viele Gründe hervorgehoben, warum Sie Ihren Code möglicherweise umgestalten möchten, aber wie Sie sagen, funktioniert es nach Spezifikation, so dass keine Kosten dafür anfallen, es so zu belassen wie es ist.

Auf der positiven Seite, wie der Code funktioniert (und sollte funktionieren) ist wahrscheinlich frisch in Ihrem Kopf, so Refactoring ist jetzt wahrscheinlich billiger als Refactoring später; Auf der anderen Seite erhöht Refactoring später mit einer tatsächlichen Änderung Anfrage die Wahrscheinlichkeit der Umgestaltung in die richtige Richtung.

In Zukunft würde ich ernsthaft darüber nachdenken, langsamer zu werden und beim Schreiben von Code weiter zu denken. Refactoring (oder Factoring!), Wie Sie gehen, ist viel einfacher und Sie haben nicht den "aber es funktioniert" Druck, einfach so zu bleiben, wie sie sind.

Sehen Sie zu. Wenn Sie feststellen, dass eine Klasse mehrere Verantwortlichkeiten zu übernehmen scheint, halten Sie inne und überlegen Sie, ob Sie die Verantwortlichkeiten in separate Klassen aufteilen müssen.

Wenn Sie bemerken, dass Sie in die Interna einer Klasse gelangen wollen, halten Sie an und überlegen Sie, wie die Schnittstelle zwischen den Klassen aussehen soll, damit Sie nicht die konkreten Einbauten einer konkreten Klasse kennen und verwenden müssen.

>     
Charles Bailey 14.05.2010 23:32
quelle
1

Arbeite an den Aspekten, die später zu Fehlern führen. Vergolden Sie nicht.

    
Paul Nathan 14.05.2010 23:42
quelle
1

Es ist eigentlich nicht so kompliziert. Folge einfach dieser Regel:

Häufig Code umgestalten. Refactor jedes Mal, wenn es möglich ist.

Wenn Sie also denken, dass Sie Ihren Code umgestalten können, sollten Sie dies jetzt tun, bevor es später, wenn alle Codes so eng zusammengezogen sind, viel komplizierter wird.

    
codingbear 15.05.2010 00:41
quelle
1

Jetzt haben Sie Ihre Referenzimplementierung. Wenn Sie sich motiviert fühlen, versuchen Sie es mit Refactoring. Hab keine Angst, wegzuwerfen und weiterzumachen oder neu zu starten.

Vielleicht wiederholen Sie die API / Schnittstelle basierend auf dem Verbrauchercode und fahren Sie das Refactoring-Top nach unten.

Sie sollten nicht wirklich daran interessiert sein, öffentliche Datenmitglieder zu haben. Die Leute schreiben viel zu viele Accessoren, die am Ende zum Spaß tippen und ehrlich gesagt die Quelle von wirklich dummen und frustrierenden Bugs (der einzige Code ohne Bugs ist Code, der nie geschrieben wurde). Das ist irritierend. Nur einkapseln, um fragile Zustände zu schützen (wenn der Elementdatenstatus gekoppelt ist).

    
brian 15.05.2010 04:33
quelle
1
  

Also, was denkt stackoverflow?   Code reinigen oder an Features arbeiten?

Die Frage, die ich hier sehe, ist der Preis, den Sie bezahlen müssen, wenn Sie umgestalten, im Gegensatz zu dem Preis, den Sie bezahlen, wenn Sie das nicht tun.

Wenn Sie es so belassen wie es ist, kostet es Sie für jede Wartung (zusätzliche Zeit, erhöhte Möglichkeit, bei jeder Änderung neue Defekte hinzuzufügen) und den Ruf als Entwickler (jeder andere Programmierer, der sich damit beschäftigt, könnte Sie wahrscheinlich verfluchen :) ).

Wenn Sie garantieren können, dass niemand diesen Code jemals wieder anfasst (nicht weil es zu schrecklich ist;)), können Sie ihn sicher so lassen, wie er ist. (In 10+ Jahren als Entwickler habe ich nie eine Situation gefunden, in der ich das garantieren konnte).

In allen anderen Fällen ist das Refactoring besser.

  

Sie sehen wie gute Gründe dafür aus   Refactor und Clean Code, Hilfe für die Zukunft   Wartung und Erweiterung, könnte aber   ziemlich zeitaufwendig sein.

Sie müssen den Code nicht perfekt machen. In der Tat, Sie sollten es eine Änderung zu einer Zeit nehmen, und Refactor in Iterationen, und wenn Sie dies richtig tun, wird es keinen anderen Code beeinflussen.

Das heißt, Sie sollten in der Lage sein, abhängig von Ihrer verfügbaren Zeit umzustukturieren, und nicht umgekehrt.

Wenn Sie beispielsweise nur eine Ihrer Mehrzweckklassen in drei oder vier separaten Klassen auflösen und den Code mit diesem Code aktualisieren, funktioniert der Rest des Codes genauso wie zuvor. Wenn Sie keine Zeit mehr haben, wenn Sie diese Änderung abgeschlossen haben, können Sie sie so lassen, wie sie ist (nur ein bisschen klarer, in nur einem Bereich).

Wenn Sie mehr Zeit haben, können Sie das nächste Refactoring machen und wiederholen.

Außerdem können Sie, wenn Sie ein verzweigtes Quellcodeverwaltungssystem verwenden, sogar parallel arbeiten, um neue Funktionen mit relativ geringen zusätzlichen Kosten zu refaktorieren und hinzuzufügen (und das Refactoring fortzusetzen, je mehr Zeit Sie haben).

    
utnapistim 13.07.2010 14:10
quelle
0

Ich würde immer Refactor sagen. Jede zusätzliche Zeile Code und alle diese kleinen kleinen Fehler kommen zurück und beißen dich in den Arsch.

In der Zukunft könnten Sie sogar umgestalten, während Sie gehen - die Zeit ist nie unbeaufsichtigt - selbst wenn Sie es wegwerfen, haben Sie immer noch gelernt, etwas Besseres zu tun.

    
Bill K 14.05.2010 23:30
quelle
0

Wenn Sie eine Reihe von Tests haben, um zu überprüfen, ob Ihr Code jetzt und nach Ihrem Refactoring funktioniert, dann würde ich sagen, wenn Sie Zeit haben, beheben Sie es, da es später mehr Zeit kostet. Aber wenn die Zeit drängt, dann ist es völlig in Ordnung, dies als Code-Schulden aufzuschreiben und zu einem besseren Zeitpunkt zurückzukommen. Wenn der Code funktioniert, können Sie jetzt eine vollkommen gute Version davon schneiden und später darauf zurückkommen, wenn Sie mehr Zeit und weniger Druck haben.

    
mdma 14.05.2010 23:40
quelle
0

Wenn Sie eine Reihe von automatisierten Tests haben, die überprüfen, ob Ihr Code richtig funktioniert, wunderbar - gehen Sie vor und refaktorieren Sie ihn; Jetzt ist die beste Zeit, während es frisch in deinen Gedanken ist. Wenn Sie es nicht tun - nutzen Sie diese Zeit, während es frisch ist, um die Tests zu schreiben. Wenn Sie nur Zeit für Tests oder Refactoring haben: Schreiben Sie die Tests so, dass es einfacher ist (manche würden es für möglich halten), sie später umzubauen.

Der TDD-Zyklus ist RED-GREEN-REFACTOR und es heißt, dass Sie erst dann "fertiggestellt" sind, wenn das Design gut ist - das heißt, bis es nicht mehr refaktorisiert werden muss.

    
Carl Manaster 15.05.2010 00:31
quelle

Tags und Links