Während wir programmieren, entwickeln wir alle Praktiken und Muster, die wir verwenden und auf die wir uns verlassen. Mit der Zeit stellen wir jedoch fest, dass einige Praktiken, die wir einst für großartig hielten, nicht (oder nicht mehr anwendbar) sind, wenn sich unser Verständnis, unsere Reife und sogar unser Technologieeinsatz ändern.
Ein Beispiel für eine Praxis, die ich einmal ziemlich oft angewendet habe, aber in den letzten Jahren geändert habe, ist die Verwendung des Singleton-Objektmusters .
Durch meine eigenen Erfahrungen und langen Debatten mit Kollegen habe ich festgestellt , dass Singletons nicht immer wünschenswert sind - sie können das Testen erschweren (indem sie Techniken wie das Verspotten hemmen) und unerwünschte Kopplungen zwischen Teilen eines Systems erzeugen. Stattdessen verwende ich jetzt Objektfabriken (normalerweise mit einem IoC-Container), die die Art und Existenz von Singletons vor Teilen des Systems verbergen, die sich nicht darum kümmern - oder wissen müssen. Stattdessen verlassen sie sich auf eine Fabrik (oder einen Service-Locator), um Zugriff auf solche Objekte zu erhalten.
Meine Fragen an die Gemeinschaft im Geiste der Selbstverbesserung lauten:
- Welche Programmiermuster oder -praktiken haben Sie in letzter Zeit überdacht und versuchen nun zu vermeiden?
- Womit haben Sie sich entschieden, sie zu ersetzen?
quelle
Einzelne Rückgabepunkte.
Ich habe einmal einen einzelnen Rückgabepunkt für jede Methode bevorzugt, weil ich damit sicherstellen konnte, dass die von der Routine benötigte Bereinigung nicht übersehen wurde.
Seitdem bin ich zu viel kleineren Routinen übergegangen - damit die Wahrscheinlichkeit, dass die Bereinigung übersehen wird, verringert wird und der Bedarf an Bereinigung verringert wird - und habe festgestellt, dass frühe Rückgaben die scheinbare Komplexität (die Verschachtelungsebene) des Codes verringern. Artefakte des einzelnen Rückgabepunkts - Beibehalten von "Ergebnis" -Variablen, Beibehalten von Flag-Variablen, Bedingungsklauseln für nicht bereits erledigte Situationen - lassen den Code viel komplexer erscheinen als er tatsächlich ist, erschweren das Lesen und Verwalten. Frühe Exits und kleinere Methoden sind der richtige Weg.
quelle
Mit einem Wort: Überentwicklung .
quelle
Ungarische Notation (sowohl Formen als auch Systeme). Früher habe ich alles vorangestellt. strSomeString oder txtFoo. Jetzt benutze ich someString und textBoxFoo. Es ist weitaus lesbarer und für jemanden, der neu ist, einfacher zu kommen und abzuholen. Als zusätzlichen Bonus ist es trivial, es konsistent zu halten - camelCase das Steuerelement und fügen Sie einen nützlichen / beschreibenden Namen hinzu. Forms Hungarian hat den Nachteil, dass es nicht immer konsistent ist und Systems Hungarian nicht wirklich viel bringt. Das Aufteilen all Ihrer Variablen ist nicht wirklich nützlich - insbesondere bei modernen IDEs.
quelle
Die "perfekte" Architektur
Ich habe mir vor ein paar Jahren DIE Architektur ausgedacht. Ich habe mich technisch so weit wie möglich geschoben, sodass es 100% lose gekoppelte Schichten, einen umfangreichen Einsatz von Delegierten und leichte Objekte gab. Es war ein technischer Himmel.
Und es war Mist. Die technische Reinheit der Architektur hat mein Entwicklerteam nur verlangsamt, um Perfektion über den Ergebnissen zu erreichen, und ich habe fast einen vollständigen Fehler erzielt.
Wir haben jetzt eine viel einfachere, weniger technisch perfekte Architektur und unsere Lieferrate ist in die Höhe geschossen.
quelle
Die Verwendung von Koffein. Es hielt mich einmal wach und in einer herrlichen Programmierstimmung, in der der Code mit fieberhafter Fließfähigkeit von meinen Fingern flog. Jetzt macht es nichts und wenn ich es nicht habe, bekomme ich Kopfschmerzen.
quelle
Code auskommentieren. Früher dachte ich, dass Code wertvoll ist und dass man nicht einfach die schönen Edelsteine löschen kann, die man hergestellt hat. Ich lösche jetzt jeden auskommentierten Code, auf den ich stoße, es sei denn, es ist ein TODO oder eine ANMERKUNG beigefügt, weil es zu gefährlich ist, ihn zu belassen. Ich bin auf alte Klassen mit riesigen auskommentierten Teilen gestoßen, und es hat mich wirklich verwirrt, warum sie waren da: wurden sie kürzlich auskommentiert? Ist dies eine Änderung der Entwicklungsumgebung? Warum macht es diesen nicht verwandten Block?
Erwägen Sie ernsthaft, den Code nicht zu kommentieren und stattdessen nur zu löschen. Wenn Sie es brauchen, ist es immer noch in der Quellcodeverwaltung. YAGNI allerdings.
quelle
Die Überbeanspruchung / der Missbrauch von # region-Direktiven. Es ist nur eine Kleinigkeit, aber in C # habe ich früher überall # region-Direktiven verwendet, um meine Klassen zu organisieren. Zum Beispiel würde ich alle Klasseneigenschaften in einer Region zusammenfassen.
Jetzt schaue ich auf alten Code zurück und ärgere mich meistens nur über sie. Ich denke nicht, dass es die Dinge die meiste Zeit wirklich klarer macht, und manchmal verlangsamen sie dich einfach. Deshalb habe ich jetzt meine Meinung geändert und bin der Meinung, dass gut angelegte Klassen ohne Regionsanweisungen größtenteils sauberer sind.
quelle
Wasserfallentwicklung im Allgemeinen und im Besonderen die Praxis, vollständige und umfassende Funktions- und Designspezifikationen zu schreiben, von denen erwartet wird, dass sie kanonisch sind, und dann zu erwarten, dass eine Implementierung dieser Spezifikationen korrekt und akzeptabel ist. Ich habe gesehen, wie es durch Scrum ersetzt wurde, und ich sage, dass es gut los ist. Die einfache Tatsache ist, dass die sich ändernde Natur der Kundenbedürfnisse und -wünsche jede feste Spezifikation effektiv unbrauchbar macht; Der einzige Weg, um das Problem wirklich richtig anzugehen, ist ein iterativer Ansatz. Natürlich nicht, dass Scrum eine Silberkugel ist; Ich habe es viele, viele Male missbraucht und missbraucht gesehen. Aber es schlägt Wasserfall.
quelle
Niemals abstürzen.
Es scheint eine so gute Idee zu sein, nicht wahr? Benutzer mögen keine Programme, die abstürzen. Schreiben wir also Programme, die nicht abstürzen, und Benutzer sollten das Programm mögen, oder? So habe ich angefangen.
Heutzutage neige ich eher dazu zu denken, dass es nicht so tun sollte, als würde es funktionieren, wenn es nicht funktioniert. Scheitern Sie so schnell wie möglich mit einer guten Fehlermeldung. Wenn Sie dies nicht tun, wird Ihr Programm nur wenige Anweisungen später noch härter abstürzen, aber mit einem unscheinbaren Nullzeigerfehler, dessen Debugging eine Stunde dauert.
Mein Lieblingsmuster "Nicht abstürzen" ist folgendes:
Anstatt Ihre Benutzer zu bitten, die Fehlermeldung zu kopieren / einzufügen und an Sie zu senden, müssen Sie jetzt in die Protokolle eintauchen, um den Protokolleintrag zu finden. (Und da sie eine ungültige Benutzer-ID eingegeben haben, gibt es keinen Protokolleintrag.)
quelle
null
oder die leere Zeichenfolge).Ich fand es sinnvoll, Designmuster anzuwenden , wenn ich sie erkannte.
Ich wusste nicht, dass ich tatsächlich Stile aus fremden Programmiersprachen kopierte, während die Sprache, mit der ich arbeitete, weitaus elegantere oder einfachere Lösungen ermöglichte.
Die Verwendung mehrerer (sehr) verschiedener Sprachen öffnete mir die Augen und machte mir klar, dass ich die Lösungen anderer Menschen nicht falsch auf Probleme anwenden muss, die nicht meine sind. Jetzt schaudert es mich, wenn ich sehe, dass das Fabrikmuster in einer Sprache wie Ruby angewendet wird.
quelle
Zwangstests. Ich war ein tollwütiger Befürworter der Test-First-Entwicklung. Für einige Projekte ist es sehr sinnvoll, aber ich habe festgestellt, dass es für viele Projekte nicht nur nicht durchführbar, sondern auch schädlich ist, sich sklavisch an eine Doktrin zu halten, Unit-Tests für jedes einzelne Stück Funktionalität zu schreiben.
Wirklich, sklavisches Festhalten an irgendetwas kann schädlich sein.
quelle
Dies ist eine kleine Sache, aber: Kümmern Sie sich darum, wohin die geschweiften Klammern gehen (in derselben oder in der nächsten Zeile?), Schlagen Sie maximale Zeilenlängen des Codes vor, benennen Sie Konventionen für Variablen und andere Stilelemente. Ich habe festgestellt, dass sich alle mehr darum zu kümmern scheinen als ich, also gehe ich einfach mit dem Fluss derer, mit denen ich heutzutage arbeite.
Bearbeiten: Die Ausnahme ist natürlich, wenn ich derjenige bin, der sich am meisten interessiert (oder derjenige ist, der in der Lage ist, den Stil für eine Gruppe festzulegen). In diesem Fall mache ich was ich will!
(Beachten Sie, dass dies nicht mit einem nicht konsistenten Stil identisch ist. Ich denke, ein konsistenter Stil in einer Codebasis ist für die Lesbarkeit sehr wichtig.)
quelle
Die vielleicht wichtigste "Programmierpraxis", über die ich seitdem meine Meinung geändert habe, ist die Idee, dass mein Code besser ist als der aller anderen. Dies ist häufig bei Programmierern (insbesondere Neulingen) der Fall.
quelle
Dienstprogrammbibliotheken. Ich habe eine Versammlung mit einer Vielzahl von Hilfsmethoden und Klassen mit der Theorie herumgetragen, dass ich sie eines Tages woanders verwenden könnte.
In Wirklichkeit habe ich gerade einen riesigen Namespace mit vielen schlecht organisierten Funktionen erstellt.
Jetzt lasse ich sie einfach in dem Projekt, in dem ich sie erstellt habe. Höchstwahrscheinlich werde ich sie nicht brauchen, und wenn ich das tue, kann ich sie später jederzeit in etwas umgestaltbares umgestalten. Manchmal werde ich sie mit einem // TODO kennzeichnen, damit sie möglicherweise in eine gemeinsame Assembly extrahiert werden können.
quelle
Mehr entwerfen als ich codiert habe. Nach einer Weile wird es zu einer Analyse-Lähmung.
quelle
Die Verwendung eines DataSet zur Ausführung der Geschäftslogik. Dadurch wird der Code zu eng an die Datenbank gebunden. Außerdem wird das DataSet normalerweise aus SQL erstellt, wodurch die Dinge noch anfälliger werden. Wenn sich SQL oder die Datenbank ändern, kann dies zu allem führen, was das DataSet berührt.
Ausführen einer Geschäftslogik in einem Objektkonstruktor. Durch die Vererbung und die Fähigkeit, überladene Konstruktoren zu erstellen, wird die Wartung in der Regel erschwert.
quelle
Abkürzung für Variable / Methode / Tabelle / ... Namen
Ich habe das die ganze Zeit gemacht, selbst wenn ich in Sprachen ohne erzwungene Beschränkung der Länge von Namen gearbeitet habe (nun, es waren wahrscheinlich 255 oder so). Eine der Nebenwirkungen waren viele Kommentare im gesamten Code, die die (nicht standardmäßigen) Abkürzungen erklärten. Und natürlich, wenn die Namen aus irgendeinem Grund geändert wurden ...
Jetzt ziehe ich es vor, Dinge so zu nennen, wie sie wirklich sind, mit guten beschreibenden Namen. einschließlich nur Standardabkürzungen . Es müssen keine nutzlosen Kommentare eingefügt werden, und der Code ist weitaus lesbarer und verständlicher.
quelle
Foo(int arg0, String arg1, float arg2)
usw.Umschließen vorhandener Datenzugriffskomponenten wie der Unternehmensbibliothek mit einer benutzerdefinierten Ebene von Hilfsmethoden.
quelle
Ich habe 1984 zum ersten Mal von objektorientierter Programmierung gehört, als ich über Smalltalk gelesen habe, aber ich hatte keinen Zugriff auf eine oo-Sprache, bis ich 1992 den Cfront-C ++ - Compiler verwendete. 1995 konnte ich schließlich Smalltalk verwenden. Ich hatte oo mit Spannung erwartet Technologie und kaufte in die Idee, dass es Software-Entwicklung sparen würde.
Jetzt sehe ich oo nur als eine Technik, die einige Vorteile hat, aber es ist nur ein Werkzeug in der Toolbox. Ich mache den größten Teil meiner Arbeit in Python und schreibe oft eigenständige Funktionen, die keine Klassenmitglieder sind, und ich sammle oft Datengruppen in Tupeln oder Listen, in denen ich in der Vergangenheit eine Klasse erstellt hätte. Ich erstelle immer noch Klassen, wenn die Datenstruktur kompliziert ist oder wenn ich ein mit den Daten verbundenes Verhalten benötige, aber ich neige dazu, mich dagegen zu wehren.
Ich bin tatsächlich daran interessiert, in Clojure zu arbeiten, wenn ich Zeit habe, was keine oo-Funktionen bietet, obwohl es Java-Objekte verwenden kann, wenn ich es richtig verstehe. Ich bin nicht bereit zu sagen, dass oo tot ist, aber ich persönlich bin nicht der Fan, der ich früher war.
quelle
In C #
_notation
für private Mitglieder verwenden. Ich finde es jetzt hässlich.Ich habe dann zu
this.notation
für private Mitglieder gewechselt , aber festgestellt, dass ich es nicht konsistent verwendet habe, also habe ich das auch fallen gelassen.quelle
this
oderMe
(C # bzw. VB.NET) zu verwenden, wenn ich Methoden und Eigenschaften aufrufe. IMO erleichtert es mir, meinen Code später leichter zu lesen und zu verstehen, insbesondere wenn sich vier oder mehr Objekte in diesem bestimmten Bereich befinden.Ich habe vor der Implementierung aufgehört, mich an die von der Universität empfohlene Entwurfsmethode zu halten. Die Arbeit in einem chaotischen und komplexen System hat mich gezwungen, meine Einstellung zu ändern.
Natürlich recherchiere ich immer noch Code, besonders wenn ich Code berühren möchte, den ich noch nie zuvor berührt habe, aber normalerweise versuche ich, mich auf so kleine Implementierungen wie möglich zu konzentrieren, um zuerst etwas in Gang zu bringen. Dies ist das Hauptziel. Verfeinern Sie dann schrittweise die Logik und lassen Sie das Design einfach von selbst erscheinen. Die Programmierung ist ein iterativer Prozess und funktioniert sehr gut mit einem agilen Ansatz und mit viel Refactoring.
Der Code sieht überhaupt nicht so aus, wie Sie es sich zuerst vorgestellt haben. Passiert jedes Mal :)
quelle
Früher habe ich mich sehr für Design-by-Contract interessiert. Dies bedeutete, dass zu Beginn aller meiner Funktionen viele Fehler überprüft wurden. Verträge sind im Hinblick auf die Trennung von Bedenken immer noch wichtig, aber anstatt zu versuchen, das durchzusetzen, was mein Code nicht tun sollte, versuche ich, mithilfe von Komponententests zu überprüfen, was er tut.
quelle
Ich würde Statics in vielen Methoden / Klassen verwenden, da es prägnanter war. Als ich anfing, Tests zu schreiben, änderte sich diese Praxis sehr schnell.
quelle
Überprüfte Ausnahmen
Eine erstaunliche Idee auf dem Papier - definiert den Vertrag klar, kein Raum für Fehler oder das Vergessen, nach Ausnahmebedingungen zu suchen. Ich wurde verkauft, als ich zum ersten Mal davon hörte.
Natürlich war es in der Praxis so ein Durcheinander. Bis zu dem Punkt, dass Bibliotheken heute wie Spring JDBC vorhanden sind, bei denen ausgeblendete Ausnahmen als eines ihrer Hauptmerkmale ausgeblendet wurden.
quelle
Dass alles, was sich lohnt, nur in einer bestimmten Sprache codiert wurde. In meinem Fall glaubte ich, dass C die beste Sprache aller Zeiten war und ich hatte nie einen Grund, irgendetwas in einer anderen Sprache zu codieren ... niemals.
Seitdem habe ich viele verschiedene Sprachen und die Vorteile / Funktionen, die sie bieten, zu schätzen gelernt. Wenn ich etwas Kleines - schnell - codieren möchte, würde ich Python verwenden. Wenn ich an einem großen Projekt arbeiten möchte, würde ich in C ++ oder C # codieren. Wenn ich einen Gehirntumor entwickeln möchte, würde ich in Perl codieren .
quelle
Als ich einige Umgestaltungen vornehmen musste, dachte ich, es sei schneller und sauberer, sofort zu beginnen und das neue Design zu implementieren und die Verbindungen zu reparieren, bis sie funktionieren. Dann wurde mir klar, dass es besser ist, eine Reihe kleiner Umgestaltungen vorzunehmen, um langsam, aber zuverlässig auf das neue Design hinzuarbeiten.
quelle
Das vielleicht größte Problem, das sich in meinen und anderen Codierungspraktiken geändert hat, ist die Akzeptanz externer Klassen und Bibliotheken, die aus dem Internet heruntergeladen wurden, als Grundlage für Verhalten und Funktionalität in Anwendungen. In der Schule zu der Zeit, als ich das College besuchte, wurden wir ermutigt, herauszufinden, wie wir die Dinge durch unseren eigenen Code verbessern können, und uns auf die Sprache zu verlassen, um unsere Probleme zu lösen. Mit den Fortschritten in allen Aspekten der Benutzeroberfläche und des Service- / Datenverbrauchs ist dies keine realistische Vorstellung mehr.
Es gibt bestimmte Dinge, die sich in einer Sprache niemals ändern werden, und eine Bibliothek, die diesen Code in eine einfachere Transaktion und in weniger Codezeilen einschließt, die ich schreiben muss, ist ein Segen. Die Verbindung zu einer Datenbank ist immer dieselbe. Die Auswahl eines Elements im DOM ändert sich nicht. Das Senden einer E-Mail über ein serverseitiges Skript wird sich nie ändern. Immer wieder schreiben zu müssen, verschwendet Zeit, die ich verwenden könnte, um meine Kernlogik in der Anwendung zu verbessern.
quelle
Initialisierung aller Klassenmitglieder.
Ich habe jedes Klassenmitglied explizit mit etwas initialisiert, normalerweise NULL. Mir ist klar geworden, dass dies:
quelle
Wie Sie habe ich auch IoC-Muster berücksichtigt, um die Kopplung zwischen verschiedenen Komponenten meiner Apps zu verringern. Dies vereinfacht die Wartung und den Austausch von Teilen erheblich, solange ich jede Komponente so unabhängig wie möglich halten kann. Ich verwende auch mehr objektrelationale Frameworks wie NHibernate, um die Datenbankverwaltung zu vereinfachen.
Kurz gesagt, ich verwende "Mini" -Frameworks, um Software schneller und effizienter zu erstellen. Diese Mini-Frameworks sparen viel Zeit und können bei richtiger Ausführung die Wartung einer Anwendung sehr einfach machen. Plug 'n Play um den Gewinn!
quelle