Ich habe viel Zeit damit verbracht, verschiedene Bücher über "gutes Design", "Designmuster" usw. zu lesen . Ich bin ein großer Fan des SOLID- Ansatzes, und jedes Mal, wenn ich ein einfaches Stück Code schreiben muss, denke ich darüber nach die Zukunft. Wenn Sie also eine neue Funktion oder eine Fehlerbehebung implementieren müssen, fügen Sie einfach drei Codezeilen wie folgt hinzu:
if(xxx) {
doSomething();
}
Das heißt nicht, dass ich es so mache. Wenn ich der Meinung bin, dass dieser Code in naher Zukunft wahrscheinlich größer wird, denke ich über das Hinzufügen von Abstraktionen, das Verschieben dieser Funktionalität an einen anderen Ort usw. nach. Das Ziel, das ich verfolge, ist es, die durchschnittliche Komplexität so zu halten, wie sie vor meinen Änderungen war.
Ich glaube, vom Standpunkt des Codes aus ist es eine gute Idee - mein Code ist nie lang genug und es ist ziemlich einfach, die Bedeutungen für verschiedene Entitäten wie Klassen, Methoden und Beziehungen zwischen Klassen und Objekten zu verstehen.
Das Problem ist, dass es zu lange dauert und ich denke oft, es wäre besser, wenn ich dieses Feature einfach so implementiere, wie es ist. Es geht nur um "drei Codezeilen" vs. "neue Schnittstelle + zwei Klassen, um diese Schnittstelle zu implementieren".
Vom Standpunkt des Produkts aus (wenn wir über das Ergebnis sprechen ) sind die Dinge, die ich tue, völlig sinnlos. Ich weiß, dass es wirklich toll ist, guten Code zu haben, wenn wir an der nächsten Version arbeiten. Andererseits wurde die Zeit, die Sie aufgewendet haben, um Ihren Code "gut" zu machen, möglicherweise für die Implementierung einiger nützlicher Funktionen aufgewendet.
Ich bin oft sehr unzufrieden mit meinen Ergebnissen - guter Code, der nur A kann, ist schlechter als schlechter Code, der A, B, C und D kann.
Wird dieser Ansatz wahrscheinlich zu einem positiven Nettogewinn für ein Softwareprojekt führen, oder ist es eine Zeitverschwendung?
quelle
Antworten:
Das riecht mir wie spekulative Allgemeinheit . Ohne zu wissen (oder zumindest einigermaßen sicher zu sein), dass Ihre Kunden die Funktionen B, C und D benötigen , überkomplizieren Sie Ihr Design nur unnötig. Komplexerer Code ist auf lange Sicht schwerer zu verstehen und zu warten. Die zusätzliche Komplexität wird nur durch nützliche Zusatzfunktionen gerechtfertigt . Aber wir sind normalerweise sehr schlecht darin, die Zukunft vorherzusagen. Die meisten der Funktionen , die wir denken , können in Zukunft benötigt werden nie im wirklichen Leben angefordert werden.
Damit:
Guter Code, der nur A kann (aber das eine ist einfach und sauber), ist BESSER als schlechter Code, der A, B, C, D kann (von denen einige möglicherweise irgendwann in der Zukunft benötigt werden).
quelle
Anekdotenzeit:
Ich habe zwei Entwickler für mich arbeiten lassen, die sich auf diese Weise der Überentwicklung verschrieben haben.
Für einen von ihnen bedeutete dies im Grunde genommen einen Stillstand seiner Produktivität, insbesondere beim Start eines neuen Projekts. Vor allem, wenn das Projekt von Natur aus ziemlich einfach war. Letztendlich brauchen wir eine Software, die jetzt funktioniert. Das wurde so schlimm, dass ich ihn gehen lassen musste.
Der andere Entwickler, der zu Überentwicklungen neigte, machte das wieder wett, indem er extrem produktiv war. Trotz des irrelevanten Codes lieferte er immer noch schneller als die meisten anderen. Jetzt, wo er fortfährt, finde ich mich jedoch oft irritiert über die Menge an zusätzlicher Arbeit, die erforderlich ist, um Funktionen hinzuzufügen, da Sie (völlig unnötige) Abstraktionsebenen usw. ändern müssen.
Die Moral ist also, dass Überengineering zusätzliche Zeit verschlingt, die besser für nützliche Dinge verwendet werden könnte. Und nicht nur Ihre eigene Zeit, sondern auch diejenigen, die mit Ihrem Code arbeiten müssen.
Also nicht.
Sie möchten, dass Ihr Code so einfach wie möglich ist (und nicht einfacher). Die Handhabung von 'Maybes' macht die Dinge nicht einfacher. Wenn Sie sich irren, haben Sie den Code komplexer gestaltet, ohne dass ein wirklicher Gewinn für ihn erkennbar wäre.
quelle
SOLID- und KISS / YAGNI-Prinzipien sind nahpolare Gegensätze. Man wird Ihnen sagen, dass, wenn doSomething () nicht als integraler Bestandteil des Jobs, den die Klasse, die es aufruft, ausführt, gerechtfertigt werden kann, es sich in einer anderen Klasse befinden sollte, die lose gekoppelt und injiziert ist. Der andere wird Ihnen sagen, dass, wenn dies der eine Ort ist, an dem etwas verwendet wird, sogar das Extrahieren in eine Methode übertrieben sein kann.
Das ist es, was gute Programmierer Gold wert macht. Die "richtige" Struktur ist von Fall zu Fall zu unterscheiden und erfordert Kenntnisse über die aktuelle Codebasis, den zukünftigen Pfad des Programms und die Bedürfnisse des Unternehmens, das hinter dem Programm steht.
Ich folge gerne dieser einfachen dreistufigen Methodik.
Im Grunde genommen mischen Sie auf diese Weise KISS mit SOLID. Wenn Sie zum ersten Mal eine Codezeile schreiben, handelt es sich, soweit Sie wissen, um eine einmalige Codezeile. Es muss einfach funktionieren und niemand kümmert sich darum, wie. Wenn Sie den Cursor zum zweiten Mal in diese Codezeile setzen, haben Sie Ihre ursprüngliche Hypothese widerlegt. Wenn Sie diesen Code erneut aufrufen, erweitern Sie ihn wahrscheinlich oder greifen von einer anderen Stelle darauf zu. Nun solltest du es ein wenig aufräumen; Extrahieren Sie Methoden für häufig verwendete Leckerbissen, reduzieren oder eliminieren Sie das Kopieren / Einfügen von Codierungen, fügen Sie ein paar Kommentare usw. hinzu. Wenn Sie zum dritten Mal zu diesem Code zurückkehren, ist dies nun eine wichtige Schnittstelle für die Ausführungspfade Ihres Programms. Jetzt sollten Sie es als einen Kernbestandteil Ihres Programms behandeln und die SOLID-Regeln anwenden, wo dies möglich ist.
Beispiel: Sie müssen eine einfache Textzeile in die Konsole schreiben. Wenn dies zum ersten Mal geschieht, ist Console.WriteLine () in Ordnung. Anschließend kehren Sie zu diesem Code zurück, nachdem neue Anforderungen auch das Schreiben derselben Zeile in ein Ausgabeprotokoll vorgeschrieben haben. In diesem einfachen Beispiel gibt es möglicherweise nicht viel sich wiederholenden "Kopieren / Einfügen" -Code (oder gibt es möglicherweise), aber Sie können dennoch einige grundlegende Bereinigungsschritte ausführen, z . Anschließend kehren Sie zurück, wenn der Client dieselbe Textausgabe an eine Named Pipe für einen Überwachungsserver wünscht. Nun, diese Ausgaberoutine ist eine große Sache; Sie senden denselben Text auf drei Arten. Dies ist das Lehrbuchbeispiel für einen Algorithmus, der von einem zusammengesetzten Muster profitieren würde. eine einfache IWriter-Schnittstelle mit einer Write () -Methode entwickeln, Implementieren Sie diese Schnittstelle, um die Klassen ConsoleWriter, FileWriter und NamedPipeWriter zu erstellen, und erstellen Sie noch einmal eine zusammengesetzte Klasse "MultiWriter". Machen Sie dann eine IWriter-Abhängigkeit von Ihrer Klasse sichtbar, richten Sie die zusammengesetzte Klasse "MultiWriter" mit den drei tatsächlichen Writern ein und schließen Sie sie an. Jetzt ist es ziemlich SOLID; Von diesem Punkt an müssen Sie nur einen neuen IWriter erstellen und an den MultiWriter anschließen, wenn die Anforderungen es erfordern, dass die Ausgabe an einen neuen Ort geht, ohne dass Sie einen vorhandenen Arbeitscode berühren müssen.
quelle
1) Haben Sie einen Code, der nur das tut, was tun soll.
2) Wenn Sie planen, dass Ihr Code A, B, C und D ausführt, werden Sie vom Kunden letztendlich nach E gefragt.
Ihr Code sollte genau das tun, was er tun soll. Sie sollten jetzt nicht über zukünftige Implementierungen nachdenken, da Sie Ihren Code ständig ändern und vor allem Ihren Code überarbeiten müssen. Sie sollten Ihren Code umgestalten, sobald Sie glauben, dass er aufgrund der vorhandenen Funktionen benötigt wird, und sich nicht abmühen, ihn auf etwas vorzubereiten, das er noch nicht tun wird, es sei denn, Sie haben ihn als Teil der Projektarchitektur geplant.
Ich empfehle Ihnen, ein gutes Buch zu lesen: The Pragmatic Programmer . Es wird Ihren Geist öffnen und Ihnen beibringen, was Sie tun und was Sie nicht tun sollten.
Auch Code Complete ist eine großartige Ressource mit nützlichen Informationen, die jeder Entwickler (nicht nur Programmierer) lesen sollte.
quelle
Vielleicht liegt hier das Problem.
In einem frühen Stadium haben Sie keine Ahnung, was das Endprodukt sein würde. Oder wenn Sie es haben, ist es falsch. Sicher. Es ist wie mit einem 14-jährigen Jungen, der vor ein paar Tagen bei Programmers.SE gefragt hat, ob er für seine zukünftige Karriere zwischen Web-Apps wählen muss, und ich erinnere mich nicht, was sonst: Es ist ziemlich offensichtlich, dass in ein paar Jahren die Dinge er wird sich gerne ändern, er wird sich für andere Bereiche interessieren, etc.
Wenn Sie zum Schreiben von drei Codezeilen eine neue Schnittstelle und zwei Klassen erstellen, sind Sie überentwickelt. Sie erhalten einen Code, der schwierig zu warten und zu lesen sein wird , nur weil Sie für jede nützliche Codezeile zwei Codezeilen haben, die Sie nicht benötigen. Ohne XML-Dokumentation, Unit-Tests usw.
Denken Sie darüber nach: Wenn ich wissen möchte, wie ein Feature in Ihrem Code implementiert ist, könnte ich zwanzig Codezeilen leichter lesen, oder es wäre schneller und einfacher, Dutzende von halb leeren Klassen und zu öffnen Schnittstellen, um herauszufinden, welche verwendet werden, in welcher Beziehung usw.?
Denken Sie daran: Eine größere Codebasis bedeutet mehr Wartung. Schreiben Sie keinen weiteren Code, wenn Sie dies vermeiden können.
Ihr Ansatz ist auch auf anderen Seiten schädlich:
Wenn Sie ein Feature entfernen müssen, ist es nicht einfacher, herauszufinden, wo eine bestimmte zwanzigzeilige Methode verwendet wird, als Ihre Zeit zu verschwenden, um die Abhängigkeiten zwischen Dutzenden von Klassen zu verstehen?
Ist es beim Debuggen nicht einfacher, einen kleinen Stack-Trace zu haben, oder möchten Sie lieber Dutzende von Zeilen lesen, um herauszufinden, was von wem aufgerufen wird?
Abschließend scheint es einer vorzeitigen Optimierung ähnlich zu sein . Sie versuchen, das Problem zu lösen, ohne überhaupt sicher zu sein, ob es überhaupt ein Problem gibt und wo es sich befindet. Implementieren Sie bei der Arbeit an Version 1 Ihres Produkts Funktionen, die Sie sofort implementieren müssen. Denken Sie nicht über etwas nach, das Sie in Version 14 in zwei Jahren implementieren werden.
quelle
Das Schreiben von viel Code, der (wahrscheinlich) nie verwendet wird, ist ein sehr guter Weg, um mit einem P45 ausgegeben zu werden . Sie haben keine Kristallkugel und keine Ahnung, in welche Richtung die Entwicklung letztendlich gehen wird. Daher kostet es Geld, Zeit für diese Funktionen zu investieren, und es gibt keine Rückkehr.
quelle
Der Versuch, vorherzusagen, was in Zukunft von Code benötigt werden könnte, führt häufig zu unnötiger Überentwicklung (eine Gewohnheit, die ich derzeit zu durchkreuzen versuche). Ich würde sagen, mach einfach die drei Zeilen. Wenn die Notwendigkeit entsteht (und nicht vorher), refactor. Auf diese Weise macht Ihr Code immer das, was er braucht, ohne übermäßig kompliziert zu sein, und entwickelt durch Umgestaltung auf natürliche Weise eine gute Struktur.
quelle
Ich sage oft, dass die Kodierung der hellen / dunklen Seite der Macht gleicht - die "helle" Seite erfordert mehr Aufwand, liefert aber bessere Ergebnisse. Die "dunkle" Seite ist schnell und einfach und bietet sofort größere Vorteile, verderbt Sie aber auf der Straße. Sobald Sie den dunklen Pfad betreten, wird er für immer Ihr Schicksal bestimmen.
Ich bin die ganze Zeit damit konfrontiert, bei jedem Job, den ich jemals hatte, ist es wie ein Fluch, dem ich nicht entkommen kann. Die Unternehmenskultur ist immer der Weg der Schattenseiten, und schnelle Hacks / Fixes, um neue Funktionen herauszubringen, und meine Bitten und Schreie, Code zu überarbeiten und richtig zu schreiben, stoßen auf taube Ohren, wenn dies nicht zu meiner Kündigung für " versuchen, Dinge zu ändern "(kein Scherz, den ich schon einige Male gemacht habe, weil ich Designmuster einführen und mich von schnellen Hacks entfernen wollte).
Die traurige Wahrheit ist, dass der dumme / dunkle Weg oft der Weg ist, den man gehen muss, man muss nur darauf achten, leicht zu treten. Ich habe langsam und traurig gemerkt, dass Programmierer, die die richtige Art und Weise, Software zu schreiben, dh SOLID zu folgen, Entwurfsmuster zu verwenden, SoC zu befolgen usw., viel seltener sind als ahnungslose Hacks, die eine
if
Erklärung schreiben , um einen Fehler zu beheben, und Wenn weitere Fehler auftreten, fügen Sie diese einfach hinzu, anstatt zu überlegen, ob es eine bessere Möglichkeit gibt, dies zu tun, und den Code so umzugestalten, dass er ordnungsgemäß erweiterbar ist.quelle
if
ist viel einfacher zu pflegen alsIAbstractBugFixer
von einemIAbstractBugFixerFactory
. Wenn und WENN Sie eine Sekunde hinzufügen müssenif
, ist es Zeit für eine Umgestaltung. Entwurfsmuster und SOLID sind während der Architekturphase sehr wichtig, jedoch nicht, wenn das Produkt bereits ausgeführt wird und in einem Stil geschrieben ist, auf den sich alle Teammitglieder geeinigt haben.Sich dessen bewusst zu sein, was passieren könnte (Zukunft), ist NIE schlecht. Überlegen, was eine bessere Möglichkeit ist, um etwas zu tun, ist ein Teil dessen, was Sie bei Ihrer Arbeit gut macht. Der schwierigere Teil ist die Bestimmung, ob das Verhältnis von Zeitaufwand zu Auszahlung gerechtfertigt ist. Wir haben alle Situationen erlebt, in denen die Leute das "einfache Wenn" tun, um die sofortige Blutung (und / oder das Schreien) zu stoppen, und dass, wie sich das zusammensetzt, Sie verwirrenden Code bekommen. Viele von uns haben auch eine übertriebene Abstraktion erlebt, die ein Rätsel ist, sobald sich der ursprüngliche Codierer weiterentwickelt, was ebenfalls verwirrenden Code erzeugt.
Ich würde auf Ihre Situation schauen und diese Fragen stellen:
Ist dieses Code-Material geschäftskritisch und wird es wesentlich stabiler, wenn ich es neu codiere? Spricht man in der Chirurgie von einer Umgestaltung des Lebensrettungsangebots, oder handelt es sich lediglich um ein Wahlfach und eine kosmetische Maßnahme?
Überlege ich, Code umzugestalten, den wir in 6 Monaten ersetzen werden?
Bin ich bereit, so viel Zeit in Anspruch zu nehmen, um das Design und meine Überlegungen für zukünftige Entwickler zu dokumentieren, wie ich für das Refactoring aufwenden muss?
Ist dies in Bezug auf mein elegantes Design zum Hinzufügen zukünftiger Funktionen ein Code, den Benutzer wöchentlich ändern möchten, oder ist dies das erste Mal, dass ich ihn in diesem Jahr berühre?
Es gibt Zeiten, in denen YAGNI und KISS den Tag gewinnen, aber es gibt Tage, in denen eine grundlegende Veränderung Sie von der Abwärtsspirale zum Verderben bringt. Solange Sie realistisch einschätzen, was nicht nur Sie wollen, sondern was andere tun müssen, um Ihre Arbeit aufrechtzuerhalten, können Sie besser bestimmen, welche Situation welche ist. Oh, und vergessen Sie nicht aufzuschreiben, was Sie getan haben und warum. Es wird diejenigen retten, die dir folgen, aber auch dich selbst, wenn du später zurückkommen musst.
quelle
In der zweiten Ausgabe von Stroustrups 'Die C ++ - Programmiersprache' (ich habe die Seite nicht zur Verfügung) habe ich gelesen
und ich bin dem Rat gut gefolgt. Natürlich gibt es Kompromisse, und Sie müssen ein Gleichgewicht finden, aber kurze Fragmente sind besser überprüfbar als ein großes Spaghetti-Durcheinander.
Ich habe oft erlebt, dass man bei der Unterscheidung zwischen einem Fall und zwei Fällen, wenn man sich 2 als n-Fälle vorstellt, viele neue Möglichkeiten eröffnet, über die man vielleicht nicht nachgedacht hat.
Aber dann muss man die YAGNI-Frage stellen: Lohnt es sich? Wird es wirklich nützlich sein? Erfahren zu sein bedeutet, dass Sie sich selten irren und als Anfänger öfter falsch liegen.
Sie sollten kritisch genug sein, um ein Muster zu erkennen und festzustellen, ob Ihr Code aufgrund zu vieler Abstraktionen schwierig zu warten oder schwierig zu warten ist, da alles an Ort und Stelle gelöst ist.
Die Lösung ist nicht dieses oder jenes, sondern darüber nachzudenken. :)
quelle
"Guter Code, der nur A kann, ist schlechter als schlechter Code, der A, B, C und D kann."
Dies kann in der Produktentwicklung sinnvoll sein. Die meisten IT-Experten arbeiten jedoch eher in „Projekten“ als in der Produktentwicklung.
Wenn Sie in 'IT-Projekten' eine gute Komponente programmieren, funktioniert diese während der gesamten Laufzeit des Projekts reibungslos. Diese darf nicht länger als 5 oder 10 Jahre dauern, da das Geschäftsszenario möglicherweise veraltet ist und ein neues Projekt / ERP vorliegt Produkt könnte es ersetzt haben. Während dieser 5/10-jährigen Lebensdauer wird niemand bemerken, dass es Fehler in Ihrem Code gibt, und die Verdienste Ihrer besten Gedanken bleiben unbemerkt! (es sei denn, Sie sind gut darin, Ihre eigene Trompete laut zu setzen!)
Nicht viele haben die Möglichkeit, Windows Ctl + Alt + Del zu programmieren, und diese wenigen haben die Chance, das Zukunftspotential ihres Codes nicht zu erkennen!
quelle
Viele Bücher über schlanke und / oder agile Entwicklung werden dazu beitragen, diesen Ansatz zu verstärken: Tun Sie, was gerade notwendig ist. Wenn Sie wissen, dass Sie ein Framework erstellen, fügen Sie Abstraktionen hinzu. Fügen Sie andernfalls erst dann Komplexität hinzu, wenn Sie es benötigen. Ich empfehle Lean Software Development , das viele andere Konzepte einführt, die einen wesentlichen Unterschied in der Produktivität bewirken können.
quelle
Es ist lustig, wie die Leute über die richtige / falsche Art und Weise reden, Dinge zu tun. Gleichzeitig ist die Programmieraufgabe immer noch sehr schwierig und es gibt keine guten Lösungen für das Schreiben großer komplexer Systeme.
Vielleicht werden wir Programmierer eines Tages endlich herausfinden, wie man komplexe Software schreibt. Bis dahin schlage ich vor, dass Sie immer zuerst mit der "blöden" Implementierung eines Prototyps beginnen und dann gerade genug Zeit für das Refactoring aufwenden, damit Ihre Colleges Ihrem Code folgen können.
quelle
Nachdem ich solche vorzeitig verallgemeinerten Entwürfe gesehen hatte, die überhaupt nicht den tatsächlichen Anforderungen entsprachen, die später kamen, entwickelte ich eine Regel für mich:
Für hypothetische Anforderungen schreiben Sie nur hypothetischen Code.
Das heißt: Sie sollten über Änderungen nachdenken, die später auftreten können. Verwenden Sie diese Erkenntnisse jedoch nur, um ein Design für den Code auszuwählen, das leicht geändert und überarbeitet werden kann, wenn diese Anforderungen tatsächlich erfüllt werden. Sie können sogar Code in Ihren Kopf schreiben (hypothetischer Code), den Sie in diesem Fall schreiben möchten, aber keinen tatsächlichen Code schreiben!
quelle
Ich denke, die Denkweise, die Ihnen dabei helfen wird, besteht darin, immer nach konkreten Lösungen für Codierungsprobleme zu streben, anstatt nach abstrakten Lösungen. Abstraktionen sollten nur hinzugefügt werden, wenn sie zur Vereinfachung der Codebasis beitragen (wenn Sie beispielsweise die Codebasis verkleinern können).
Viele Programmierer haben festgestellt, dass Abstraktionen fast von selbst entstehen, wenn sie ihren Code DRY up. Design Patterns und Best Practices helfen Ihnen dabei, Möglichkeiten dafür zu finden, sind aber an sich keine Ziele, die es wert sind, verfolgt zu werden.
quelle
Ich denke, dass Überentwicklung oft durch Unsicherheit beim Schreiben von Code hervorgerufen wird. Alle abstrakten Prinzipien und Muster sollten als Hilfsmittel behandelt werden. Was oft passiert ist, dass sie als Standards behandelt werden, denen man sich anpassen muss.
Ich glaube, dass ein Programmierer immer besser in der Lage ist zu entscheiden, wie er abstrahiert als ein Axiom.
Der Rest wurde bereits von KeithS gesagt
quelle
Fragen Sie sich, was die Vorteile eines guten Designs sind:
Fragen Sie sich nun, ob das Hinzufügen all dieser Abstraktionsebenen tatsächlich zu einem der oben genannten Punkte beiträgt. Wenn nicht, machst du es FALSCH .
Wenn Sie durch Hinzufügen von 3 Codezeilen wie folgt neue Funktionen hinzufügen können:
Dann bitte, bitte tu es. Dies zeigt an, dass Ihr vorheriges Design gut und einfach anzupassen war. Erst wenn Ihre Klassen über ein bestimmtes Maß hinaus wachsen, können Sie mithilfe von Refactoring Funktionen aufteilen und möglicherweise neue Klassen extrahieren.
Meine Faustregel lautet, dass neue Funktionen so minimalistisch wie möglich implementiert werden sollten. Nur wenn etwas zu groß ist, um es im Voraus zu erfassen (die Implementierung dauert beispielsweise mehr als einen Tag oder einen halben Tag), können Sie ein grobes globales Design hinzufügen. Fügen Sie von da an nur noch Abstraktionsebenen hinzu, wenn der Code größer wird. Sie überarbeiten danach! Nach einer Weile sollte es für Sie sogar selbstverständlich sein, wenn Sie ein Stück mehr entwerfen oder sich auf die schnelle Straße begeben müssen. Ein weiterer Hinweis, den ein Code zur Bereinigung verwenden kann, ist die Wiederverwendung. Jedes Mal, wenn Sie eine neue Funktion hinzufügen oder alten Code an einem neuen Ort aufrufen, ist es eine gute Zeit, den alten Code zu überprüfen und zu prüfen, ob Sie ihn ein wenig verbessern können, bevor Sie ihn erneut hinzufügen. Auf diese Weise wird heißer Code langsam sauberer, während die uninteressanten Teile langsam verrotten und keine wertvolle Zeit in Anspruch nehmen.
Wenn Sie so arbeiten, werden Sie nie etwas überzeichnen. Es kann eine gewisse Disziplin erfordern, zum alten Code zurückzukehren, wenn Sie etwas Neues hinzufügen möchten, oder den neuen Code etwas hässlicher zu lassen, als Sie möchten, aber Sie werden auf etwas Produktives hinarbeiten, anstatt auf etwas Überentwickeltes.
quelle