Dumm sein, um die Produktivität zu steigern?


112

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?


141
Ich werde deinen SOLID sehen und dich rasie YAGNI und KISS
jk.

16
Boom, Kopfschuss.
Robert S.

16
Das Problem des "Over-Engineerings" ist manchmal die Manifestation eines Anforderungserfassungsprozesses, der nicht richtig funktioniert. Wenn Sie mit "Was-wäre-wenn" zu kämpfen haben und diese dann OHNE die Interaktion eines Interessenvertreters / Kunden selbst beantworten, sind Sie in der Lage, die Zukunft vorherzusagen. Nehmen Sie sich vielleicht etwas Zeit, um die Anforderungen besser zu verstehen, bevor Sie den Code komplexer gestalten.
Angelo

4
Vielleicht bin ich es nur, aber ich würde es für "dumm" halten, meinen Klienten / Arbeitgeber dazu zu bringen, Geld auszugeben, um etwas zu haben, das er / sie nicht angefordert / gewünscht hat: S
Thomas Bonini

2
Es wird so gut wie nie schwieriger sein, ein Feature in Zukunft hinzuzufügen, wenn es tatsächlich benötigt wird. Sie gewinnen nichts, wenn Sie es jetzt tun.
Hardwareguy

Antworten:


153

Guter Code, der nur A kann, ist schlechter als schlechter Code, der A, B, C, D kann.

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).


87
+1 für "Wir sind normalerweise sehr schlecht darin, die Zukunft vorherzusagen" Der Benutzer wird höchstwahrscheinlich nach E fragen :)
Michał Piaskowski

1
+1 Konnte nicht mehr zustimmen. Ich habe vor kurzem ein Arbeitssemester in einem Unternehmen beendet und dies würde ich als die wichtigste Lektion betrachten, die ich gelernt habe.
Wipqozn

4
@ Michał, ist das eine Vorhersage? ;-)
Péter Török

10
Selbst wenn sie dich nach D fragen, werden sie wahrscheinlich ein anderes mentales Modell haben und nach einer etwas anderen Art von D fragen, die deine Abstraktionen nicht unterstützen ...
Chris Burt-Brown

"Wenn ein Problem nicht vollständig verstanden wird, ist es wahrscheinlich am besten, überhaupt keine Lösung bereitzustellen" oder "Fügen Sie keine neuen Funktionen hinzu, es sei denn, ein Implementierer kann eine echte Anwendung ohne diese nicht fertigstellen." gilt hier. Via en.wikipedia.org/wiki/X_Window_System#Principles
nwahmaet

87

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.


10
+1 für so einfach wie möglich, aber nicht einfacher.
Julian

33
"Ein Designer weiß, dass er Perfektion erreicht hat, nicht wenn nichts mehr hinzuzufügen ist, sondern wenn nichts mehr wegzunehmen ist." Antoine de Saint-Exupery
Arkh

Vermeiden Sie Wiederholungen wie die Pest und Sie werden nicht viel falsch machen.
Kevin

@arkh ... Ich wollte das gleiche Zitat verwenden: P
Michael Brown

6
Ich würde es so ausdrücken: Jede Codezeile ist mit hohen Kosten verbunden. Minimieren Sie also die Kosten, indem Sie den Code minimieren. Das Löschen von unnötigem Code ist ebenso produktiv (möglicherweise sogar produktiver) als das Schreiben von neuem Code.
Kristopher Johnson

26

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.

  • Lass es beim ersten Durchgang funktionieren.
  • Machen Sie es beim zweiten Durchgang sauber.
  • Machen Sie es beim dritten Durchgang SOLID.

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.


Einverstanden, aber normalerweise, wenn Sie den ersten Schritt hinter sich haben, können Sie nicht mehr zum zweiten oder dritten zurückkehren, da die Funktion jetzt "live" ist und weitere Funktionen in Kürze verfügbar sind erste Funktion. Sie feststellen , dass alle Sie tun können , ist der erste Schritt mit ist jede Funktion und dann bist du mit einem Sumpf verlassen.
Wayne Molina

2
@Wayne M - Dies kann in SDLC-Wasserfällen oder in Kurzzeitszenarien durchaus vorkommen. In diesen Fällen wird nicht die Wartbarkeit des Codes bewertet, sondern die Erledigung der Arbeit gemäß den ursprünglichen Spezifikationen bis zum Abgabetermin. Wenn Sie die Qualität des Quellcodes bewerten möchten, müssen Sie einfach Zeit in den Zeitplan für das Refactoring einbauen. So wie Sie die Qualität von Inhalten bei jedem anderen Auftrag, bei dem es um die Erstellung schriftlicher Informationen geht, schätzen, nehmen Sie sich Zeit für das Überprüfen und Bearbeiten.
KeithS

Ihre Eröffnungslinie ist irreführend - Sie sagen, dass sie sich widersetzen, und beschreiben dann den besten Weg, sie gemeinsam zu nutzen. Ich weiß nicht, ob ich für die schlechte Linie oder für den guten Rat positiv stimmen soll.
Sean McMillan,

1
Ich glaube nicht, dass ich mir selbst widersprochen habe. Sie sind nahpolare Gegensätze; religiöses Festhalten an dem einen oder anderen bedeutet notwendigerweise Ablehnung des anderen. Das bedeutet jedoch nicht, dass sie sich gegenseitig ausschließen; Sie müssen sich nicht dafür entscheiden, sich zu 100% an beide Methoden zu halten. Das war der Punkt des Restes der Antwort; Wie stellen Sie ein Gleichgewicht her, wenn Sie aus den Schlussfolgerungen der einzelnen Prinzipien ein Geben und Nehmen ziehen?
KeithS

Wirklich schöner Prozess: funktioniert, sauber, fest. Ich frage mich, ob eine Konsequenz daraus ist: "Versuchen Sie nicht, etwas zu konstruieren, ohne vorher einen Prototyp gehackt zu haben."
Steve Bennett

17

Guter Code, der nur A kann, ist schlechter als schlechter Code, der A, B, C, D kann.

1) Haben Sie einen Code, der nur das tut, was tun soll.

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.

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.


12

Gerade wenn ich ein einfaches Stück Code schreiben muss, denke ich über die Zukunft nach

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.


"Dutzende von halb leeren Klassen" haben den zusätzlichen Nachteil, dass nicht genügend Material vorhanden ist, um zu verstehen, wofür diese Klassen gut sind.
gnasher729

5

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.


3

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.


3

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 ifErklä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.


3
ifist viel einfacher zu pflegen als IAbstractBugFixervon einem IAbstractBugFixerFactory. Wenn und WENN Sie eine Sekunde hinzufügen müssen if, 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.
Coder

@Coder Versuchen Sie nicht anzunehmen, dass sich die Architektur zu keinem Zeitpunkt ändern kann. Es kann und tut.
Ricky Clarkson

1
Wayne M, ich kann mich in Ihre Arbeitssituationen einfühlen. Bleib bei der Macht. :)
Jennifer S

3

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:

  1. 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?

  2. Überlege ich, Code umzugestalten, den wir in 6 Monaten ersetzen werden?

  3. 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?

  4. 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.


3

In der zweiten Ausgabe von Stroustrups 'Die C ++ - Programmiersprache' (ich habe die Seite nicht zur Verfügung) habe ich gelesen

Fügen Sie Code nicht spontan hinzu.

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. :)


2

"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!


1

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.


1

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.


1
In den meisten Fällen haben Sie nie eine spezielle Zeit für das Refactoring - das ist wahrscheinlich der Hauptgrund für all diese "Wir können dies nicht implementieren, ohne dies erneut zu implementieren" ;-) Sie tun es entweder von Anfang an richtig , oder du machst es die ganze Zeit falsch.
Andrey Agibalov

@ loki2302: Vergiss nicht, dass das Schreiben von neuem Code immer einfacher ist. Sie werden doppelt so schnell sein, wenn Sie dummen Code erstellen. Danach sinkt Ihre Produktivität für etwa die Hälfte der Zeit auf Null.
Am

1

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!


0

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.


0

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


Ich denke, eine Möglichkeit, sich beim Schreiben von Code selbst zu schützen, besteht darin, auf einem Linux-System als root zu codieren. Wenn Sie "Boom" eingeben, müssen Sie nur ein neues Image der VM erstellen. Unterrichtet alle Arten von guten Gewohnheiten sehr schnell. Stellen Sie sicher, dass Ihre Box im Internet verfügbar ist, und sehen Sie sich die Protokolle an. (ssh, http) Das macht auch richtig Spaß!
Christopher Mahan

Meine Version lautet: Ignoriere Prinzipien, die du nicht verstehst. Wenn Sie sie verwenden möchten, sollten Sie sie nicht ernsthafter behandeln als eine Übung.
Sabof

0

Fragen Sie sich, was die Vorteile eines guten Designs sind:

  • Leichter zu verstehen
  • Einfacher zu pflegen
  • tragbar
  • Bleibt lange nützlich
  • Einfach, neue Funktionen hinzuzufügen

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:

if (condition()) {
  doSomething()
}

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.