Wo sollte Code-Refactoring und -Optimierung sowohl in eine agile als auch in eine Wasserfall-Prozess-Zeitleiste passen?

10

Es scheint diese Vorstellung im Projektmanagement-Team zu geben, dass "es funktioniert" bedeutet, dass es dann als 100% vollständig angesehen werden sollte. Die meisten Programmierer wissen, dass dies nicht immer der Fall ist. Wenn ich alternative Ansätze versuche, um eine Funktion zum Laufen zu bringen, bedeutet dies nicht unbedingt, dass ich die beste Lösung gefunden habe, oder es sind keine Nacharbeiten erforderlich, nachdem ich sie mit anderen Entwicklern besprochen habe. Ich werde oft mit etwas fertig, einen Schritt zurücktreten und mich dann fragen, was ich besser machen kann, wenn die Geschäftsregeln erfüllt sind. Sollte diese "Ich kann es besser machen" -Zeit tatsächlich irgendwo in die Zeitleiste passen? Ich bin der Meinung, dass der beste Ansatz darin besteht, Code immer besser zu belassen, als wenn Sie ihn gefunden haben (bis zu einem gewissen Grad), was ein Refactoring nach dem Start bedeuten könnte. Jedoch,


quelle

Antworten:

13

Es gibt ein übergeordnetes Prinzip, das die Notwendigkeit einer Umgestaltung und Optimierung sowohl im Wasserfall als auch in Agile regelt: YAGNI (Sie werden es nicht brauchen). Ein zweites Prinzip ist die Folge des ersten: "Vorzeitige Optimierung ist die Wurzel allen Übels", das Kodierungsäquivalent des allgemeinen Sprichworts "Der Feind der Exzellenz ist Perfektion".

Nehmen wir die Prinzipien und wenden sie an. Sie müssen einen ETL-Algorithmus erstellen, der eine Datei eines bestimmten Typs verwendet, deren Informationen extrahiert und diese Informationen dann in eine Datenbank einfügt. Ihr Ziel für diese Woche (für unsere Zwecke spielt es keine Rolle, ob Sie sich in einem Agile- oder SDLC-Shop befinden) ist es, dies zu erreichen.

Sie sind ein kluger Kerl, und Sie haben einen Einblick in das Gesamtbild erhalten. Sie wissen, dass dies nicht der einzige Dateityp ist, für den das Projekt eine ETL benötigt. Sie sollten diesen ETL-Algorithmus so implementieren, dass er auch für einen anderen Dateityp funktioniert, der nur geringfügige Unterschiede aufweist. Dies würde YAGNI verletzen. Ihre Aufgabe ist es nicht, den Algorithmus für diese andere Datei zu entwickeln. Es soll der Algorithmus für die eine Datei entwickelt werden, die bis Ende der Woche benötigt wird. Um dieses Ziel zu erreichen und die Abnahmetests zu bestehen, müssen Sie diesen Algorithmus entwickeln und ordnungsgemäß funktionieren lassen. Sie werden den zusätzlichen Code "nicht brauchen", damit er mit der anderen Datei funktioniert. Sie denken vielleicht, es spart Ihnen Zeit, es jetzt zu integrieren, und Sie haben vielleicht Recht, aber Sie könnten auch furchtbar falsch liegen. Der Algorithmus für die andere Datei muss möglicherweise in einem Bereich des Systems verwendet werden, in dem Ihr Code nicht verwendet werden kann, oder die Anforderungen für die neue Datei unterscheiden sich möglicherweise von denen für Ihre in einer Weise, die Sie nicht kennen (in Agile diese) Anforderungen existieren möglicherweise noch nicht). In der Zwischenzeit haben Sie Zeit verschwendet und die Komplexität Ihres Algorithmus unnötig erhöht.

Jetzt ist es nächste Woche, und als zweifelhafte Belohnung für Ihre hervorragende Arbeit am ersten Algorithmus wurde Ihnen die Aufgabe übertragen, die Algorithmen für zwei neue Dateitypen zu erstellen. Jetzt benötigen Sie zusätzlichen Code, damit Ihr Algorithmus mit mehr Dateien funktioniert. Sie können Ihren vorhandenen Algorithmus mithilfe eines Vorlagenmethodenmusters erweitern, das ein Grundmuster mit dateispezifischen Einzelschritten verwendet, oder Sie können einfach eine gemeinsame Schnittstelle aus Ihrem vorhandenen Algorithmus ableiten, zwei neue entwickeln, die der Schnittstelle folgen, und sie anschließen Ein Objekt, das auswählen kann, welcher Algorithmus verwendet werden soll.

Während der Entwicklung wissen Sie, dass das System 10 KB Rohdaten pro Sekunde verarbeiten muss. Sie führen einen Auslastungstest durch und stellen fest, dass Ihr anfänglicher Entwurfsalgorithmus 8 KB / s verarbeitet. Nun, das wird die AATs nicht bestehen. Sie werfen einen Blick darauf und sehen, dass Ihr Algorithmus eine O (mein Gott) -Komplexitätsschleifenstruktur enthält. Sie rationalisieren es und erhalten 12 KB / s. "Ziemlich gut", denken Sie, "aber wenn ich eine so schlechte Schleife im Code hätte, was kann ich sonst noch rasieren?". Buzz Sie haben gerade die Regel "Vorzeitige Optimierung" verletzt. Ihr Code funktioniert und erfüllt alle Anforderungen. Sie sind "fertig", bis die Anforderungen auf 15 KB / s aktualisiert werden. In diesem Fall ziehen Sie den Code zurück und suchen nach Verbesserungsmöglichkeiten.

Befolgen Sie diesen einfachen Prozess während der Entwicklung, ob in Agile oder in herkömmlichen SDLCs: "Lassen Sie es beim ersten Durchgang funktionieren. Machen Sie es beim zweiten Durchgang hübsch. Beim dritten Durchgang machen Sie es SOLID." Wenn Sie zum ersten Mal eine Codezeile erstellen, müssen Sie dafür sorgen, dass dieser Code seine Aufgabe korrekt und fehlerfrei erledigt. Achten Sie jedoch nicht zu sehr auf die Entwurfsregeln in diesem Code, wie Sie alles wissen, was Sie gerade wissen. ' Ich werde diesen Bereich nie wieder berühren. Wenn Sie das nächste Mal diese Codezeile besuchen, haben Sie sich einfach als falsch erwiesen. Es ist kein einmaliges Teil des Systems mehr. Refactor es für Lesbarkeit, Prägnanz des Codes und / oder DRY-Prinzipien (Sie haben möglicherweise einen Code kopiert, um etwas fünfmal zu tun; Refactor das in eine Schleife und / oder einen Methodenaufruf). Wenn Sie zum dritten Mal in oder um diese Codezeile arbeiten,

KeithS
quelle
3
+1 für O(my God)-complexitywenn nichts anderes, brachte mich zum Lachen!
Joel C
+1 für Lass es zuerst funktionieren. Zu viele Leute versuchen, Muster zu schreiben und vorzeitig zu optimieren.
Justin Shield
Ich finde, dass dies eines der schwierigsten Probleme ist, die als Programmierer zu lösen sind. Ingenieure haben den angeborenen Wunsch zu experimentieren, sich zu entwickeln und zu verfeinern, aber am Ende des Tages werden Sie für die Produktivität bezahlt. Was nützt ein perfektes Produkt, wenn Sie so viel Zeit und / oder Geld investieren, dass es aufgrund von Überschreitungen storniert wird?
ToddR
Ich mag den pragmatischen Ansatz, aber ich habe ein Problem mit "Beim zweiten Durchgang machen Sie es hübsch": Wenn der zweite Durchgang ein Jahr später ist und Sie nicht sicher sein müssen, dass Variablen- und Methodennamen sinnvoll sind und magische Zahlen durch symbolische Konstanten ersetzt wurden Sie haben wahrscheinlich Probleme, den Code zu verstehen. Wie gehe ich damit um? "Mach es hübsch" 1 Stunde nach "mach es schön" ist viel billiger als "mach es hübsch" nach einem Monat oder nach einem Jahr. Ich bin damit einverstanden, dass "mach es hübsch", wenn die nächste Codeänderung notwendig ist, nützlich ist, wenn "mach es hübsch" überhaupt nicht gemacht wurde.
k3b
In Agile / TDD habe ich die Erfahrung gemacht, dass der zweite Durchgang normalerweise ziemlich bald nach dem ersten erfolgt. In wasserfallähnlichen SLDCs haben Sie mehr Recht. Die Funktion wird in der Regel einmal geschrieben und befindet sich dann dort, bis die nächste Anforderungsrunde abgeschlossen ist, die diese Methode berührt. Daher müssen beim ersten Mal einige gute Codierungsmethoden angewendet werden, z. B. selbstdokumentierender Code, damit Sie sich ein Jahr später daran erinnern können, was der Code tut und warum Sie ihn so geschrieben haben.
KeithS
10

Wenn es funktioniert und getestet wurde, warum dann beheben?

Dies mag Ihrem persönlichen Temperament als Ingenieur / Programmierer zuwiderlaufen, aber wenn es funktioniert, welchen geschäftlichen Wert haben Sie dann, um es weiter zu verfeinern? Wird es einfacher sein, im Laufe der Zeit zu warten? Wenn dies der Fall ist, sollten Sie nach der agilen Methodik in der Lage sein, neue Elemente in Ihrem Backlog zu erstellen, um Ihren vorhandenen Code zu verfeinern und umzugestalten. Diese Elemente werden dann mit den anderen Elementen im Backlog priorisiert. Das ist Teil des Wertes des agilen Prozesses: Das Team entscheidet gemeinsam, was am wichtigsten ist und was als nächstes getan wird.

Unser Team verfolgt auch das, was wir als "technische Schulden" bezeichnen. Wenn Sie also etwas zum Laufen bringen, aber wissen, dass es besser gemacht werden kann, protokollieren Sie es als technische Schulden. Wir verwenden Scrum, und manchmal beenden Sie die gesamte Arbeit in einem Sprint früh (Sie sollten ungefähr die Hälfte der Zeit etwas früher fertig sein, wenn Sie den Schätzungen ziemlich nahe kommen), haben aber nicht genug Zeit, um einen völlig neuen zu erstellen User Story, also verbringen wir die zusätzliche Zeit damit, zurück zu gehen und unsere technischen Schulden abzubauen. Es wird nicht formal wie unsere User Stories in unserem Backlog verfolgt, und wir können so ziemlich daran arbeiten, wann immer wir Zeit haben.

Es ist auch mehr oder weniger ein Urteilsspruch von Ihrer Seite, wenn Sie die Aufgabe als "erledigt" bezeichnen. Wenn Sie mit dem Status Ihres Codes nicht vertraut sind, markieren Sie die Aufgabe nicht als abgeschlossen.

Joel C.
quelle
2
Ich bin ein Fan des "Technical Debt" -Konzepts geworden, +1, weil ich es in diesem Zusammenhang angesprochen habe.
Patrick Hughes
Die Idee der "technischen Verschuldung" völlig vergessen; guter Begriff. Mir wurde jedoch beigebracht, dass alles, was als "technische Verschuldung" eingestuft wurde, was bedeutet, dass für die Umgestaltung erhebliche Entwicklerzyklen erforderlich wären, vermieden werden sollte. "mach es leicht" bedeutete immer noch "mach es richtig", gehe einfach nicht "Elfenbeinturm" auf Code, der einmalig sein könnte.
KeithS
5

Sollte diese "Ich kann es besser machen" -Zeit tatsächlich irgendwo in die Zeitleiste passen?

Ja.

Kurz bevor Sie mit dem Codieren der nächsten Version beginnen.

Refactor nicht basierend auf "Intuition".

Refactor basierend auf den tatsächlichen Geschichten des nächsten Sprints.

S.Lott
quelle
2

Markieren Sie den Code erst dann als 100% vollständig, wenn Sie mit dem Refactoring zufrieden sind. Sie müssen nur ständig die Kosten / Nutzen für die Umgestaltung des Codes bewerten, denn wenn Sie genug studieren, werden Sie immer Möglichkeiten sehen, den Code besser zu machen.

Ich verwende die rot-grüne Refaktormethode von TDD. Mein Refactoring ist also in meine Entwicklung integriert. Für große Umgestaltungen wie das Ändern des zugrunde liegenden Modells oder ähnliches würde ich das Management dazu bringen, sich zu beteiligen, um zuerst die Zeit zu verbringen.

mpenrow
quelle
1
Der Code ist erst dann "100% vollständig", wenn alle Produkte, in denen er sich befindet, tot sind. Ähnlich wie Sie als Person nicht "vollständig" sind, bis Ihr Herz aufhört, dauerhaft zu schlagen; Sie werden immer neue Informationen aufnehmen und bestimmte Dinge tun müssen, die Sie noch nie zuvor getan haben, oder dasselbe auf eine neue, effizientere oder kostengünstigere Weise tun. Ebenso benötigt Ihre Codebasis IMMER Arbeit - neue Funktionen und alte Korrekturen - bis niemand mehr die Software verwendet.
KeithS
2

"Refactoring nach dem Start" hat versteckte Kosten für Regressionstests und QS-Zeit, die Sie ignorieren. Außerdem entstehen Opportunitätskosten, wenn Sie nicht an gemeldeten Fehlern und neuen / angeforderten Funktionen und Änderungen arbeiten. TANSTAAFL

Wenn es sich lohnt, eine Aufgabe zu erledigen, um Prioritäten zu setzen, und nicht als besondere Ausnahme. Schließlich sind Sie Teil eines Teams, und wenn Sie an gemeinsamen Zielen arbeiten und Ihren Zeitplan willkürlich erweitern, um das Korrigieren des Arbeitscodes zu berücksichtigen, wirkt sich dies auch auf sie aus.

Für eine echte Antwort: Wenn Sie wissen, dass Sie eine Umgestaltung vornehmen möchten, planen Sie diese Zeit als Teil der Aufgabe. Wenn Sie Scrum / Agile ausführen, müssen Sie eine Bereinigungsaufgabe ausführen. Wenn Sie ein Wasserfall / eine Spirale sind, machen Sie den Refactor zu einem Teil des Prozesses, um den Code zu überprüfen und die Module zu akzeptieren.

Patrick Hughes
quelle
0

Wenn ich alternative Ansätze versuche, um ein Stück Funktionalität zum Laufen zu bringen, heißt das nicht unbedingt, dass ich die beste Lösung gefunden habe.

... In diesem Fall sind Sie noch nicht zu 100% fertig ...

oder es erfordert keine Nacharbeit nach Überprüfung mit anderen Entwicklern.

Wenn Codeüberprüfungen und nachfolgende Nacharbeiten Teil Ihres Entwicklungslebenszyklus sind, wird die Funktion erst ausgeführt, wenn alle diese abgeschlossen sind.

Ich werde oft mit etwas fertig, einen Schritt zurücktreten und mich dann fragen, was ich besser machen kann, wenn die Geschäftsregeln erfüllt sind. Sollte diese "Ich kann es besser machen" -Zeit tatsächlich irgendwo in die Zeitleiste passen?

Es hängt davon ab, ob. Wenn es sich um Refactoring handelt, sollte es Teil der ursprünglichen Entwicklungsaufgabe sein. Wenn es bedeutet, mit einem möglicherweise besseren Algorithmus zu experimentieren, könnte dies eine separate Aufgabe sein.

Ich bin der Meinung, dass der beste Ansatz darin besteht, Code immer besser zu belassen, als wenn Sie ihn gefunden haben (bis zu einem gewissen Grad), was ein Refactoring nach dem Start bedeuten könnte. Projektteams fühlen sich mit diesem Ansatz jedoch oft sehr unwohl, denn wenn er funktioniert und getestet wurde, warum sollte er dann behoben werden?

Kurz gesagt, weil Code auf vielen Ebenen gebrochen werden kann.

Es ist eine Sache, die es gerade funktioniert. Es ist eine ganz andere Sache, ob es auf lange Sicht sauber, erweiterbar und wartbar ist.

Ausführlichere Antworten finden Sie in diesem Thread .

Péter Török
quelle
0

Soweit ich sehen und gelesen habe, ist dies eine ungeklärte Frage. Daher antworten die Vermeidungsantworten wie "YAGNI" und "Do-it-Right-the-First-Time-Antworten". Tatsache ist, dass es in Agile keinen Platz für Refactoring gibt - aber ich würde argumentieren, dass es einen geben sollte.

Die bisher beste Antwort erwähnt technische Schulden. Dies ist leider eine traurige Realität von Software in vielen Unternehmen, in denen die Eile, Dinge in einer agilen oder nicht agilen Methodik nach draußen zu bringen, allzu häufig ist - aber unter Agile die schnellen und schmutzigen Lösungen werden als etwas Gutes rationalisiert: "Erfüllt die Mindestanforderungen an das Geschäft" und "YAGNI" (im Hinblick auf die Sauberkeit des Codes).

Es wäre großartig, wenn alle TDD machen würden, und es wäre großartig, wenn alle Entwickler das zweite oder dritte Mal umgestalten würden, wie in einer Antwort vorgeschlagen. Aber das passiert in der realen Welt einfach nicht. Entwickler mit unterschiedlichen Fähigkeiten haben fast immer Abstriche bei der Suche nach schnellen Lösungen gemacht. Infolgedessen zerfällt der Code in Berge von nicht wartbarem Code, dessen Entschlüsselung neue Entwicklertage in Anspruch nimmt, was die Produktivität beeinträchtigt und die Fristen verzögert. Mit "nicht wartbar" meine ich Copy-and-Paste-Lösungen, 5000 Zeilenklassen usw. Und all dieser Code und diese Korrekturen sind das Kernstück des Geschäfts! - In diesen Fällen von additiven Lösungen würde ich argumentieren, dass es YAGNI nicht gibt! Sie benötigen IMMER sauberen Code. Wenn der Code nicht sauber ist, werden Sie ihn definitiv nicht brauchen - sehen Sie die sich selbst erfüllende Prophezeiung? Entwickler würden große Anstrengungen unternehmen, um diesen Code überhaupt nicht zu verwenden, da es zu schmerzhaft ist, ihn anzusehen. Und der Teufelskreis geht weiter und weiter, bis der ganze große Schlammballen weggeschmissen und neu geschrieben werden muss.

Ich sage also - obwohl Code-Refactoring kein richtiges, eigenständiges und seiner eigenen Geschichte würdiges agiles Konzept ist - sollten wir uns Zeit für das Refactor nehmen. In einigen Geschäften müssen Teams jetzt 20% ihrer Sprints für technische Schulden ausgeben. Hoffentlich werden die agilen Befürworter ihre Meinung zu YAGNI ändern und einen Ort für das Refactoring als separate zeitlich festgelegte Aktivität schaffen. Und wenn sie es bereits getan haben und ich noch nichts davon gehört habe, zeigen Sie bitte darauf, wo das beschrieben ist, weil ich sehr interessiert bin, es zu wissen.

blindcodifier9734
quelle
"Tatsache ist, dass es in Agile keinen Platz für Refactoring gibt" - ich denke nicht, dass dies eine wahre Aussage ist. In Agile gibt es einen Platz für jede Art von Entwicklung, einschließlich Refactoring, solange es einen Business Case dafür gibt. Wenn es keinen Business Case dafür gibt, warum machst du das dann?
Bryan Oakley
Ich denke, Sie haben einen Punkt, wenn auch ein bisschen simpel. Theoretisch könnte ein Entwickler einen Business Case für die Behebung von fehlerhaftem Code erstellen, selbst wenn er keine funktionalen Änderungen hervorruft. Dies würde jedoch nicht dem Geist der Agilität entsprechen - das Geschäft als Proxy zu verwenden, um die Arbeit zu rechtfertigen. Ich würde dann argumentieren, dass die Aktivität des Refactorings außerhalb des Bereichs der Agilität liegt - eine Art CYA-Aktivität, wenn Sie so wollen -, um nicht wartbaren Code zu reparieren, damit er das Geschäft langfristig nicht kostet und die Entwickler beschuldigt werden. Nennen wir es einen "Refactoring-Sprint" oder was auch immer, aber es muss einen formellen Ort dafür geben.
Blindcodifier9734