Überbeanspruchte oder missbrauchte Programmiertechniken [geschlossen]

38

Gibt es Techniken in der Programmierung, die Sie als überbeansprucht empfinden (dh viel überbeansprucht, als was sie sein sollten) oder missbraucht oder ein bisschen für alles benutzt haben, ohne eine wirklich gute Lösung für viele der Probleme zu sein, die die Leute versuchen damit lösen.

Es können reguläre Ausdrücke sein, eine Art Entwurfsmuster oder vielleicht ein Algorithmus oder etwas völlig anderes. Vielleicht denken Sie, die Leute missbrauchen Mehrfachvererbung usw.

Anto
quelle
33
Ich bin damit einverstanden, dass der Internet Explorer weitaus häufiger verwendet wird, als es eigentlich sein sollte, aber das ist in erster Linie von Nicht-Programmierern. . .
Eric Wilson
7
@ FarmBoy - Ich denke, er meinte IE: "Dh" steht einfach für "das heißt", was vollständig in Latein geschrieben ist, ist "id est".
Raphael
Behoben jetzt :)
Anto
4
Jede Technik kann (und wird oft missbraucht), sie muss nur als nächste Silberkugel präsentiert werden, und Sie werden jemanden finden, der jedes Problem als Nagel behandelt (um Metaphern zu mischen).
ChrisF
8
@ Rapheal - ich habe natürlich nur Spaß gemacht. Danke für die Ausbildung.
Eric Wilson

Antworten:

73

Kommentare im Code

Ich wünschte nur, die Universitätsprofessoren würden verstehen, dass sie ihren Studenten nicht beibringen müssen, 10 Kommentarzeilen zu schreiben, wobei der folgende Code eine for-Schleife ist und von 1 bis zur Zahl x iteriert. Ich kann das im Code sehen!

Bringen Sie ihnen bei, zuerst selbstdokumentierenden Code zu schreiben und dann angemessen zu kommentieren, was als zweites nicht ausreichend selbstdokumentierend sein kann. Die Software-Welt wäre ein besserer Ort.

Dan McGrath
quelle
26
Selbstdokumentierender Code ist nicht. Auch Professoren lehren die Schüler, das Problem zu konzipieren und wie sie es angehen sollen. Außerdem habe ich noch nie jemanden gesehen, der sich über zu viel Dokumentation beschwert. Vorsichtsmaßnahme ist die Dokumentation korrekt.
Woot4Moo
24
@ Woot4Moo: Wenn Sie lesen Clean Code, stellt Fowler klar fest, dass veraltete Dokumentation schlechter ist als keine Dokumentation, und dass alle Kommentare dazu neigen, veraltet zu werden und vom dokumentierten Code abzuweichen. In diesem ganzen Buch geht es darum, selbstdokumentierenden Code zu schreiben.
Scott Whitlock
12
Ihnen
beizubringen
15
+1. Ich habe tatsächlich Folgendes im Code der realen Welt gesehen: "loopVar ++; // loopVar inkrementieren". AAAAAAAAAAAAARRRRRGH!
Bobby Tables
7
@Bill: Ich gehe davon aus, dass Sie keine generischen Logik- und Kontrollstrukturen dokumentieren müssen, auch wenn diese relativ komplex sind. Grundsätzlich sollte alles, was ein guter Entwickler, der die Sprache kennt, durch Analyse des Codes herausfinden kann, nicht kommentiert werden müssen. z.B. Eine Reihe von verschachtelten for-Schleifen mit einigen Unterbrechungen usw. Was jedoch zu kommentieren ist, ist die anwendungsspezifische Begründung, warum der Code diese Entscheidungen trifft: z. "Wenn ein neuer Programmierer morgen bei der Firma anfängt und sich den Code ansieht, macht es dann Sinn, wenn er keine Kommentarhinweise enthält?"
Bobby Tables
57

Das Singleton-Entwurfsmuster.

Sicher, es ist ein nützliches Muster, aber jedes Mal, wenn ein neuer Programmierer von diesem Muster erfährt, versucht er, es auf jede einzelne Klasse anzuwenden, die er erstellt.

Raphael
quelle
Ich benutze diese schlecht gestaltete Ausrede jeden Tag für einen Rahmen. codeigniter.com/user_guide/libraries/email.html Sie denken, dass OOP Funktionen voranstellt$this-> . PHP ist eine faule Sprache, daher kann ich nicht erwarten, dass die Frameworks exzellent sind.
Keyo
7
Ich denke, jeder Programmierer, der einen Singleton implementiert und nicht bereut, wird für die Sünde, die er (oder sie) begangen hat, in der Hölle brennen.
2
Ich habe einmal in meiner beruflichen Laufbahn einen Singleton implementiert (im Multitasking-Kontext) und musste meine Sünde bereuen, indem ich sie neu schrieb.
Spoike
3
Singletons können für ein paar Dinge nützlich sein, werden aber fast immer verwendet, wenn sie nicht sein sollten. Das bedeutet nicht, dass Singletons niemals verwendet werden sollten - nur weil etwas missbraucht wird, heißt das nicht, dass es nicht richtig verwendet werden kann.
Konfigurator
2
@Rapahel: Genau deshalb halte ich das Studium von Designmustern nicht für eine gute Sache.
Konfigurator
53

Das Schlimmste, um dumme Programme zu schützen. alles in einen Versuchsfang stecken und nichts mit dem Fang machen

        try
        {
            int total = 1;
            int avg = 0;
            var answer = total/avg;
        }
        catch (Exception)
        {

        }

Ich schaudere, wenn ich einen Versuchsfang sehe, der nichts bewirkt und auf dumme Logik ausgelegt ist. Im Allgemeinen werden Versuchsfänge überstrapaziert, in einigen Fällen sind sie jedoch sehr nützlich.

Nickz
quelle
4
Lustige Sache - Ich habe gerade eine Datei bearbeitet, die dies Hunderte Male tut, und das aus gutem Grund. Es ist eine Unit-Test-Datei, die testet, dass verschiedene Methoden eine Ausnahme auslösen, wenn sie erwartet werden. Der try-Block enthält einen Aufruf und den Bericht "Erwarteter Wurf ist nicht aufgetreten". Die Ausnahme wird erwartet und ist korrekt, daher gibt es keine Korrekturmaßnahme. Offensichtlich sind Unit-Tests ein Sonderfall, aber ich habe ähnliche Fälle in echtem Code gehabt. Rote Fahne, ja, aber keine absolute Regel.
Steve314
5
@Steve der Fall, den Sie beschrieben haben, ist eine seltene Randbedingung. Eine andere, die mir einfällt, ist das Protokollieren von Code. Wenn die Protokollierung selbst fehlschlägt, macht es keinen Sinn, die Ausnahme zu protokollieren oder die App zu unterbrechen.
dbkk
1
@dbkk - stimmte der Randbedingung zu, und ich füge hinzu, dass Sie, wenn Sie wirklich eine Ausnahme abfangen müssen, aber keine Korrekturmaßnahme benötigen, einen Kommentar in den catch-Block einfügen, um zu erklären, dass dies wesentlich ist, wenn Sie nur die Situation beruhigen wollen Betreuer. Es ist nicht so selten in Unit-Tests, also würde ich den Kommentar in diesem Fall fallen lassen.
Steve314
5
bei fehler weiter fortsetzen
jk.
2
@ jk01 - eine Ausnahme ist (nicht unbedingt) ein Fehler. Ob eine Bedingung ein Fehler ist oder nicht, hängt vom Kontext ab. Beispielsweise ist "Datei nicht gefunden" kein Fehler, wenn Sie die Datei nicht benötigen. Vielleicht ist es nur eine optionale Einstellungsdatei, die vorhanden sein kann oder nicht, und Sie können Ihre Standardeinstellungen einfach beibehalten, wenn die Datei nicht vorhanden ist (daher sind nach dem Abfangen keine Korrekturmaßnahmen erforderlich).
Steve314
47

Verlassen Sie sich auf StackOverflow, um Ihre Probleme zu lösen, anstatt es auf die harte Tour zu schaffen.

Neue Programmierer, die die Fülle des Wissens in SO-Posts (zu oft) finden, bevor sie überlegen und Dinge ausprobieren.

Zu meiner Zeit mussten wir aus Büchern codieren, kein Internet, kein SO. Jetzt geh runter von meinem Rasen.

Byron Whitlock
quelle
28
Ich muss zugeben, ich zucke bei der Kühnheit einiger Fragen zu SO zusammen. Entweder weil sie jeden Tag oft gefragt werden und offensichtlich überhaupt nicht gesucht haben; oder noch schlimmer, sie behandeln die Community als kostenlosen Outsourcing-Service.
Orbling
2
@dbkk: stackoverflow.com/questions/4665778/… -> erster Kommentar " Haben Sie das jemals versucht?"
Matthieu M.
5
Ich habe angefangen, aus Büchern zu lernen, aber als ich ein Grundwissen hatte, habe ich fast alles andere aus Online-Forumsdiskussionen gelernt. Nicht durch Fragen, sondern hauptsächlich (und zunächst ausschließlich) durch Lesen. Diese Methode hat mir mehrere Programmiersprachen in einer unglaublichen Tiefe beigebracht (mit vielen Ecken und Kanten), und ich denke, es ist überhaupt keine schlechte Methode.
Konrad Rudolph
1
@Konrad Rudolph: Diese Methode ist gut und weise, Fragen lesen, gut suchen. Das Fragen ist am besten erledigt, wenn der Fragende einen Rahmen hat, mit dem er die Antworten verstehen kann. Zu oft stellen Menschen Fragen, die sie (noch) nicht verstehen können.
Orbling
3
Das Problem ist, dass SO dies fördern, indem Sie viel Repräsentanten für das Stellen / Beantworten sehr einfacher Fragen geben, die mit einer einfachen Google-Suche beantwortet werden können. Sehr schwierige Frage, die die Leute nur beantworten, weil sie es wirklich wollen.
IAdapter
36

OOP offensichtlich. Es ist sehr wertvoll, aber wenn es missbraucht wird , kann es anderenfalls den Code ziemlich leicht verdecken (einige Beispiele für die S4-Programmierung in R fallen mir ein), und es kann einen enormen Overhead verursachen, der unnötig ist und Sie viel Zeit für die Leistung kosten kann.

Eine andere Sache ist, dass (in zB Perl) OOP oft darauf hinausläuft, dass das Gleiche umgekehrt geschrieben wird: result = $object ->function(pars)Stattdessen ist result = function(object, pars)dies manchmal sinnvoll, aber wenn es mit prozeduraler Programmierung vermischt wird, kann es das Lesen des Codes ziemlich verwirrend machen. Und abgesehen davon führen Sie einfach mehr Overhead ein, wenn das Design dadurch nicht verbessert wird. Es kommt auch darauf an, was über das Singleton-Muster gesagt wird: Sollte verwendet werden, aber nicht auf allen.

Ich benutze OOP selbst, aber in meinem Bereich (wissenschaftliches Rechnen) ist die Leistung eine große Sache, und OOP wird dort oft missbraucht, da heutzutage alle Studenten Java bekommen. Es ist großartig, um größere Probleme zu lösen, zu konzipieren und so weiter. Wenn Sie jedoch z. B. mit DNA-Sequenzen in BioPerl arbeiten, können Sie die Berechnungszeit verzehnfachen, wenn Sie die Objekte jedes Mal verwenden und konsequent mit Gettern und Setzern arbeiten. Wenn Ihr Code ein paar Tage anstatt ein paar Stunden ausgeführt wird, ist dieser Unterschied wirklich wichtig.

Joris Meys
quelle
6
@Craige: Ich benutze OOP selbst, aber in meinem Bereich (wissenschaftliches Rechnen) ist Leistung eine große Sache, und OOP wird dort oft missbraucht, da heutzutage alle Studenten Java bekommen. Es ist großartig, um größere Probleme zu lösen, zu konzipieren und so weiter. Wenn Sie jedoch z. B. mit DNA-Sequenzen in BioPerl arbeiten, können Sie die Berechnungszeit verzehnfachen, wenn Sie die Objekte jedes Mal verwenden und konsequent mit Gettern und Setzern arbeiten. Wenn Ihr Code ein paar Tage anstatt ein paar Stunden ausgeführt wird, ist dieser Unterschied wirklich wichtig.
Joris Meys
1
@Craige: Das Verketten von Methoden (wie Foo.DoX().DoY().DoZ()) ist zwar nett, aber definitiv nicht die einzige Möglichkeit, etwas zu tun . Funktionszusammensetzung (wie doZ . doY . doX $ fooist eine absolut gültige Alternative.
Anon.
1
@Joris: Etwas, worüber ich mich schon lange gewundert habe (ich selbst Bioinformatiker): Wenn die Leistung so wichtig ist, warum sollte ich Perl statt C ++ verwenden? Wenn Sie sich Sorgen machen, einen Faktor 10 nach der Laufzeit zu verlieren (berechtigtes Anliegen!), Können Sie sofort zu C ++ wechseln. Natürlich ist die Sprache scheiße ... aber Perl auch ... und es gibt gute Bioinformatik-Bibliotheken für C ++.
Konrad Rudolph
1
@Konrad: Kommt drauf an. BioPerl hat wohl die meisten Pakete für Bioinformatiker aus allen Sprachen (ich glaube, Python holt auf). Außerdem wurde in Perl eine Menge Arbeit geleistet, und das Anpassen eines Skripts ist einfacher als das Umschreiben von Inhalten in C ++. Schließlich dient es nicht dazu, eine vollständige Anwendung zu schreiben, wenn ein Skript ausreicht. Vermutlich ist Perl deshalb immer noch so weit verbreitet. Und ehrlich gesagt macht es mir nichts aus, ich mag die Sprache. Es ist immer noch das Beste, was ich für die Arbeit mit Strings und Dateien kenne. Die Berechnungen werden offensichtlich in anderen Sprachen durchgeführt und verlinkt (was ziemlich einfach ist).
Joris Meys
1
@Konrad: es kommt darauf an, wie man es macht. Es ist möglich, alles in Perl zu tun, aber Perl kann problemlos mit anderen Tools verknüpft werden, insbesondere unter Linux. Ich verwende Perl oft als erweitertes Bash-Skript mit starker String-Manipulation und einfacher Konstruktion von Datensätzen, die in andere Anwendungen verschoben werden sollen.
Joris Meys
27

Nachdem ich einige Jahre in ASP.NET Webforms verbracht habe, muss ich eindeutig sagen:

Die intelligente Benutzeroberfläche

Während es durchaus möglich ist, mehrschichtige, testbare Anwendungen in Webforms zu erstellen, ist es für Entwickler in Visual Studio zu einfach, Formulare mit nur einem Klick an ihre Datenquelle zu binden, da sich die Anwendungslogik um den gesamten UI-Code dreht.

Steve Sanderson erklärt dieses Anti-Pattern viel besser als ich es in seinem Pro ASP.NET MVC-Buch könnte:

Um eine Smart UI-Anwendung zu erstellen, erstellt ein Entwickler zunächst eine Benutzeroberfläche, indem er normalerweise eine Reihe von Benutzeroberflächen-Widgets auf eine Zeichenfläche zieht, und füllt dann den Ereignishandlercode für jeden möglichen Tastenklick oder jedes andere Benutzeroberflächenereignis aus. Die gesamte Anwendungslogik befindet sich in diesen Ereignishandlern: Logik zum Akzeptieren und Validieren von Benutzereingaben, zum Durchführen von Datenzugriff und -speicherung sowie zum Bereitstellen von Feedback durch Aktualisieren der Benutzeroberfläche. Die gesamte Anwendung besteht aus diesen Ereignishandlern. Dies ist im Wesentlichen die Regel, die standardmäßig ausgegeben wird, wenn Sie einen Anfänger vor Visual Studio stellen. Bei diesem Design gibt es keinerlei Trennung von Bedenken. Alles ist miteinander verschmolzen und nur in Bezug auf die verschiedenen UI-Ereignisse angeordnet, die auftreten können. Wenn Logik- oder Geschäftsregeln in mehr als einem Handler angewendet werden müssen, wird der Code normalerweise kopiert und eingefügt. oder bestimmte zufällig ausgewählte Segmente werden in statische Dienstprogrammklassen zerlegt. Aus so vielen offensichtlichen Gründen wird diese Art von Entwurfsmuster oft als Antimuster bezeichnet.

richeym
quelle
1
Eine GUI ist mindestens eine Art von Spezifikationscode, der eingehalten werden muss. Ich glaube nicht, dass die Programmierer, die er beschreibt, es besser machen würden, wenn sie stattdessen eine leere Textdatei hätten.
4
@qpr, das weiß ich nicht. Wenn sie eine leere Textdatei hätten, könnten sie möglicherweise nichts tun (was nur ein Bonus sein könnte).
Ken Henderson
Einer der vielen Vorteile der Verwendung von WPF besteht darin, dass durch die Implementierung von MVVM dieses Antimuster in Stücke gerissen wird.
Robert Rossney
2
Tausendmal so. Ich sehe sogar erfahrene .NET-Entwickler, die sich auf dieses "Muster" verlassen, weil es einfacher ist, die Trennung von Bedenken zu verstehen oder sich darum zu kümmern. Auch wenn sie die Drag-and-Drop-Assistenten nicht verwenden, besteht das häufigste "Muster" in der .NET WebForms-Entwicklung darin, alles in Code-Behind-Ereignissen zu tun und Code nach Bedarf zu kopieren / einzufügen.
Wayne Molina
23

Ich sehe das gelegentlich und es resultiert normalerweise daraus, dass man boolesche Ausdrücke nicht vollständig versteht.

if (someCondition == true)
Corey
quelle
16
Es hat den Vorteil, dass der Code expliziter wird
Pemdas
7
Ich denke, ein Blick auf diese Frage ist angebracht: programmers.stackexchange.com/questions/12807/…
gablin
5
Ich mache das nicht, aber im Ernst, komm darüber hinweg. Es gibt verdammt viel Schlimmeres da draußen. :)
MetalMikester
4
Wenn Sie Ihre Variablen richtig benannt haben, zum Beispiel bools beginnend mit isoder has, müssen Sie Ihren Code nicht expliziter mit machen = true.
Niemand
3
@ DisgruntledGoat, weil es überhaupt nicht verwendet werden sollte
Corey
19

Neuimplementierung der Kernfunktionalität (oder anderweitig bereitgestellter Funktionen), entweder aufgrund der Unkenntnis ihrer Existenz oder aufgrund eines wahrgenommenen Anpassungsbedarfs.

l0b0
quelle
2
Lernen ist eine Ausnahme. Wenn man etwas studiert, ist es oft nützlich, "das Rad neu zu erfinden".
Maxpm
Sicher - ich hätte angeben sollen, dass es nur beim Erstellen von Produktionssoftware relevant ist.
l0b0
1
Dies ist besonders schlimm, wenn Sie Sicherheitsaspekte implementieren. Gute Sicherheitssoftware verhindert Angriffe, an die die meisten Menschen gar nicht denken.
David Thornley
Ich sehe das viel zu häufig. Wir brauchen X, schreiben wir selbst! Aber was ist mit Open-Source-Paket Y? Nein, wir brauchen kundenspezifische Software für unsere supergeheimen Geschäftsgeheimnisse, die die gleichen sind wie alle anderen in unserer Branche. Wir können keine gängige Müllsoftware verwenden!
Wayne Molina
18

Erbe.

Nicht erzwingen ist dort, wo es keinen Sinn ergibt.

Kit
quelle
6
Das Problem ist, dass intuitiv „is-a“ sehr oft sinnvoll erscheint (zumal jede Implementierungs- / Vertragsbeziehung umgangssprachlich als „is-a“ ausgedrückt werden kann). Es erfordert ein solides Verständnis von OOP, um zu erkennen, dass dies tatsächlich ein Fehler ist und dass Vererbung und Schnittstellenimplementierung sich grundlegend unterscheiden.
Konrad Rudolph
@Konrad - stimme absolut zu. Ich versuche, die Leute zu ermutigen, mit der Komposition zu beginnen , zu Schnittstellen überzugehen und die Vererbung als letztes in Betracht zu ziehen. (Als Faustregel natürlich). Aber vielleicht ist das mein VB-Hintergrund ;-)
Mike Woodhouse
1
Dies ist jedoch größtenteils eine Frage des Sprachdesigns. Der Grund, warum Sie in Sprachen wie Java oder C # "die Komposition der (Implementierungs-) Vererbung vorziehen" sollten, ist, dass die Implementierungsvererbung in diesen Sprachen nicht funktioniert. Einige Leute kritisieren die objektorientierte Softwarekonstruktion von Bertrand Meyer wegen Überbeanspruchung der Vererbung, aber wenn Sie sich Eiffel (die in dem Buch verwendete Sprache) ansehen, stellen Sie fest, dass es für die Implementierungsvererbung entwickelt wurde , und daher ist es in Ordnung, Vererbung zu verwenden Zusammensetzung. Zumindest in diesem Fall.
Jörg W Mittag
14

Anpassen von Standard-Software.

Obwohl ich zugeben kann, dass dies nützlich sein kann, frage ich mich, wie viel Geld dafür ausgegeben wird, kleine Dinge für fragwürdige Gewinne zu erledigen. Hier kann ein Unternehmen Hunderttausende, wenn nicht Millionen von Dollar für Lizenzen für eine Software ausgeben, die dann angepasst wird, da sie so konfigurierbar, bearbeitbar und flexibel ist, dass sie standardmäßig nicht viel bewirkt. Am Ende ist es eine benutzerdefinierte Anwendung, da der gesamte neue Code hinzugefügt wurde, was ursprünglich gekauft wurde.

JB King
quelle
Ist dies bei einer benutzerdefinierten Anwendung nicht wahrscheinlicher?
JeffO
13

Verwenden des Compliers als Debugger.

Ignorieren Sie die entsprechenden Warnungen oder schalten Sie sie vollständig aus.

Globale Variablen.

Pemdas
quelle
18
Was ist los mit "Verwenden des Compilers als Debugger"? Ein Compiler, der in der Lage ist, auf Fehler in Ihrem Code hinzuweisen, bevor sie zur Laufzeit zu einem Problem werden, ist ein enormer Vorteil.
Mason Wheeler
3
Ich verlasse mich darauf, dass der Compiler meine Syntaxfehler und falschen Typzuordnungsfehler abfängt. Bei Verhaltensfehlern verlasse ich mich auf Testfälle.
Gablin
5
Das Problem ist, wenn Sie sich auf den Compiler verlassen müssen, um die Programmkorrektheit sicherzustellen. Hat das kompiliert? Nein, lassen Sie mich diesen kleinen Abschnitt durchgehen und sehen, ob er dadurch behoben wurde. Hat es kompiliert? Nein, lassen Sie mich hier und da ein * hinzufügen und nachsehen, ob kompiliert wird. ... ect. Offensichtlich ist es nützlich für die Korrektur von Tippfehlern
Pemdas
2
Sie sagen, dass der Programmierer blind im Dunkeln herumstochert und versucht, irgendetwas zu tun, um den Code irgendwie kompilieren zu lassen. So funktioniert IME nicht. Der Compiler gibt Ihnen eine nützliche Fehlermeldung und weist Sie auf den Ort des Fehlers hin. Wenn etwas nicht kompiliert wird, haben Sie in der Regel selbst einen neuen Code geschrieben, sodass Sie eine gute Vorstellung davon haben, was falsch ist und wie Sie es beheben können, wenn darauf hingewiesen wurde aus. (Auch wenn Sie zufällige * s herumwerfen, arbeiten Sie möglicherweise in C ++, wo Compiler-Fehler bekanntermaßen äußerst wenig hilfreich sind. Daher trifft das, was ich sagte, möglicherweise nicht zu.)
Mason Wheeler
3
Sich auf den Compiler zu verlassen, funktioniert sehr gut, vorausgesetzt, das Typsystem ist stark genug und die Codebasis ist gut geschrieben. Oft ist die Art System kann wichtige Einschränkungen modellieren , dass Sie sonst Tests schreiben müßten für (zB in schwach typisierte Systemen). Wenn der Compiler (und insbesondere der Typprüfer) mit Bedacht eingesetzt wird, ist er eine großartige Ressource zum Testen und Debuggen, und es ist nichts Falsches daran, sich darauf zu verlassen. Insbesondere ist es falsch zu sagen, dass ein Compiler nur Syntaxfehler anzeigen kann.
Konrad Rudolph
11

Alle Entwurfsmuster.

Sie sind wie Salz oder Zucker. Einige von ihnen auf Ihrem Essen machen es großartig, viele von ihnen machen Ihr Essen zum Kotzen.

Versteh mich nicht falsch. Design Patterns sind wunderbare Techniken. Ich habe sie oft benutzt. Aber manchmal finde ich Programmierer (einige von ihnen meine Ex-Chefs), die diese "Sie müssen ein Entwurfsmuster verwenden" hatten, auch wenn das Problem nicht passt !!!

Ein Beispiel ist das "Besuchermuster", das sich eher an "lineare / sequentielle Sammlungen" richtet. Ich musste einmal mit einer Baumdatenstruktur arbeiten. Um jeden Artikel zu "besuchen", codiere ich eine Nicht-Design-Pattern-Methode, und ein ehemaliger Chef besteht darauf, das "Visitor Pattern" zu verwenden oder anzupassen. Dann suche ich im Internet nach einer zweiten Meinung. Nun, andere Programmierer hatten die gleiche Situation und die gleiche Lösung. Und nennen Sie es das "Tree / Hierarchical Visitor Pattern" (Baum / Hierarchisches Besuchermuster) als NEUES Entwurfsmuster

Ich hoffe, dass es in einer neuen Version des Buches "Design Patterns" als neues Muster zu den bestehenden hinzugefügt wird.

umlcat
quelle
3
Ich verwende niemals Entwurfsmuster, obwohl sie in meinem Code manchmal auf natürliche Weise vorkommen.
Konfigurator
Wie geht das Sprichwort? Sie fangen an, Muster zu verwenden, ohne zu wissen, dass Sie sie verwenden, lernen sie dann kennen und verwenden sie überall, und dann werden sie zur zweiten Natur, sodass Sie anfangen, sie zu verwenden, ohne zu wissen, dass Sie sie verwenden?
Wayne Molina
2
@configurator Wenn ich etwas über die Entwurfsmuster lese; Ich entdecke auch, dass ich und andere Entwickler bereits einige von ihnen verwendet haben ;-)
umlcat
9

Ausnahmen als Flusskontrolle verwenden. Ähnlich wie diese Antwort , aber anders.

Das Verschlucken von Ausnahmen ist eine schlechte Form, da sie mysteriöse, schwer zu findende Fehler in Code einführt. Die Verwendung von Ausnahmen als Ablaufsteuerung ist dagegen schlecht, da der Code dadurch weitaus ineffizienter als er sein könnte und konzeptionell schlampig ist.

Die Ausnahmebehandlung sollte nur verwendet werden, um wirklich außergewöhnliche (duh), unvorhergesehene Szenarien zu behandeln, und nicht, wenn ein Benutzer ein alphabetisches Zeichen eingibt, für das eine Zahl erwartet wird. Diese Art von Ausnahmebedingungsmissbrauch ist unter schlechten Programmierern in der Java-Welt äußerst verbreitet.

Bobby Tables
quelle
Ausnahmen, die zu ineffizientem Code führen, hängen von Ihrer Sprache ab - Erstellen eines Stack-Frames usw. usw. In Squeak ist Ihr Stack vollständig angepasst, sodass es keinen Unterschied gibt, ob Sie Ausnahmen verwenden oder nicht. (Mit anderen Worten, Ausnahmen sind Teil der Bibliothek, nicht der Sprache.) Es ist jedoch verwirrend , mit ausnahmegesteuerten Kontrollabläufen zu arbeiten: lshift.net/blog/2011/01/04/try-again-with-exceptions shows Eine Schleife mit Ausnahmen, die ich kürzlich gefunden habe.
Frank Shearar
Auch beim letzten Absatz kommt es auf Ihre Sprache an. Ausnahmen ("Bedingungen") in Common Lisp sind eine strikte Obermenge der Vorstellungen der meisten Sprachen von Ausnahmen. Beispiele finden Sie hier: gigamonkeys.com/book/… Wie bei allem, können Sie zu weit gehen!
Frank Shearar
Lesbarkeit und Wartbarkeit überwiegen die Leistung. Die Fälle, in denen ich Ausnahmen für den Erfolg verwende (was ich als "Flusskontrolle" bezeichne), sind sehr selten, aber sie können beispielsweise bei einer komplexen rekursiven Suche einen saubereren Code liefern. Im Großen und Ganzen stimme ich jedoch zu. Zum Beispiel habe ich Behälter mit Iteratormethoden dass return false für Reichweite Ausgehen (gemeinsam am Ende einer Iteration), aber eine Ausnahme aus , wenn der Iterator ist „null“ (ein wahrscheinliches Zeichen für eine Art inneren Widersprüchlichkeit)
Steve314
7

Ich werde mit Unflexibilität durch übermäßiges Verstecken von Daten gehen.

Wir alle wissen, dass Abstraktion und das Ausblenden der Implementierung gut sind, aber mehr ist nicht immer besser. Wenn Sie dies übertreiben, erhalten Sie ein unflexibles Ergebnis, das Änderungen der Anforderungen nicht bewältigt. Um die Änderung zu verarbeiten, müssen Sie nicht nur die Klasse ändern, die diese Änderung verarbeiten muss, sondern Sie müssen auch eine Methode erstellen, mit der auf die Informationen zugegriffen werden kann, die zuvor nicht benötigt wurden, obwohl sich Datenschichten verstecken.

Das Problem ist, wie bei allen Problemen, bei denen es darum geht, für jeden Kontext das richtige Gleichgewicht zu finden, dass es Erfahrung erfordert.

Steve314
quelle
6

Veränderlicher Zustand und Schleifen. Sie brauchen sie fast nie und Sie bekommen fast immer besseren Code ohne sie.

Dies wird beispielsweise direkt von einem StackOverflow-Thread übernommen:

// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
    thing = things[i];
    if(things_by_type[thing.type]) {
        things_by_type[thing.type].push(thing);
    } else {
        things_by_type[thing.type] = [thing];
    }
}

# Ruby
things_by_type = {}
things.each do |thing|
  (things_by_type[thing.type] ||= []) << thing
end

Sie machen beide dasselbe. Aber ich habe keine Ahnung, was sie tun. Glücklicherweise erklärt die Frage tatsächlich, was sie tun, sodass ich sie wie folgt umschreiben konnte:

// ECMAScript
things.reduce(function (acc, thing) {
    (acc[thing.type] || (acc[thing.type] = [])).push(thing);
    return acc;
}, {});

# Ruby
things.group_by(&:type)

// Scala
things groupBy(_.type)

// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);

Es gibt keine Schleifen und keinen veränderlichen Zustand. Okay, keine expliziten Schleifen und keine Schleifenzähler.

Der Code ist viel kürzer, viel einfacher, viel weniger fehleranfällig als vielmehr eine Beschreibung dessen, was der Code tun soll (insbesondere im Ruby-Fall sagt er ziemlich direkt "Gruppiere die Dinge nach Typ"). Es besteht keine Gefahr, dass das Ende des Arrays verrutscht, Zaunpfostenfehler oder einzelne Fehler mit den Schleifenindizes und Beendigungsbedingungen auftreten, da keine Schleifenindizes und Beendigungsbedingungen vorliegen.

Jörg W Mittag
quelle
Ich glaube, dass in der zweiten Zeile Ihres "festen" ECMAScripts anstelle von (acc[thing.type] || (acc[thing.type] = []))"= [thing] thing" , unless you want to add zweimal auf der Liste stehen sollte ... Oder vermisse ich etwas?
Austin Hyde
@ Austin Hyde: Du hast recht.
Jörg W Mittag
1
Dieses Ecmascript-Beispiel ist für viele Programmierer unverständlich. Es basiert auf zu vielen syntaktischen Tricks. Die Schleife hat den Vorteil der Übersichtlichkeit für Nachwuchsentwickler.
Joeri Sebrechts
6

Verspottung. Es bringt zu viele künstliche Anforderungen für eine übermäßige Entkopplung in Ihren Code mit sich, führt zu überentwickeltem Ravioli-Code und zwingt OO-artiges Design in Ihren Hals, wenn ein prozeduraleres oder funktionaleres Design eine einfachere Lösung für Ihr Problem sein könnte.

dsimcha
quelle
In der Theorie einverstanden; Mocks sind nützlich, aber man muss sie nicht haben .
Wayne Molina
Die Invasivität von Spott hängt von der Sprache ab, die Sie verwenden. In C # kann es sehr invasiv sein und viele nicht benötigte Schnittstellen hinzufügen.
Frank Hileman
3

Delphi-Programmierer auf der ganzen Welt haben in den letzten zwei Jahren herausgefunden, wie schlecht es ist, Zeichen-Arrays aufgrund der vollständigen Unicode-Konvertierung zum Speichern von Bytes zu verwenden

Und "bald" werden wir erfahren, wie schlecht es ist, Ganzzahlen in Listen zu speichern, wenn wir die Änderung auf 64-Bit vornehmen möchten .

Peter Turner
quelle
2
Ich glaube, ein großer Teil der Unicode-Probleme wäre nie aufgetreten, wenn Borland einen DataString-Typ deklariert hätte, der im Grunde derselbe wie AnsiString war, aber speziell für die Verwendung mit Blobs gedacht war, und dann sichergestellt hätte, dass die Leute davon erfahren.
Mason Wheeler
2

Eigenschaften. Ich weiß, dass dies umstritten ist, aber ich habe das Gefühl, dass Eigenschaften in .net stark überbeansprucht werden.

Was ist der Unterschied zwischen diesen beiden Zeilen?

public string Property { get; set; }

public string Field;

Für den Entwickler ist der Unterschied: absolut nichts. Die kompilierter Form ist ein winzig bisschen anders, wenn Sie also eine Bibliothek schreiben, und diese Bibliothek wird in Programmen aktualisiert werden, und Sie können die Programme nicht neu kompilieren selbst (zum Beispiel , wenn Sie eine Schnittstelle für Plugins schreiben , welche sollten für alle Versionen Ihrer Software funktionieren), dann sollten Sie keine öffentlichen Felder verwenden, da Sie diese nicht durch Eigenschaften ersetzen können. In jedem anderen Fall gibt es keinen Unterschied zwischen der Verwendung eines Felds oder einer Auto-Eigenschaft ohne Modifikatoren.

Konfigurator
quelle
1
Einverstanden; Wenn Sie zu 100% wissen, dass Sie eine "Eigenschaft" erhalten / festlegen müssen, gibt es keinen Grund, eine Eigenschaft zu haben. Wenn jedoch die Möglichkeit besteht, dass Sie etwas tun müssen (z. B. protokollieren, dass ein Wert geändert wurde), sollten Sie eine Eigenschaft verwenden. Persönlich habe ich nicht groß genug Unterschied zu nicht die Eigenschaft verwenden, falls Sie zu tun Notwendigkeit , es zu ändern später (ich weiß, ich weiß , YAGNIaber ich fühle mich in diesem Fall abweichend kostet nichts)
Wayne Molina
2
@ Wayne: Wie wechselt man ;zu { get { ... } set { ... } }mehr Arbeit als { get; set; }zu { get { ... } set { ... } }?
Konfigurator
Nun, da ich darüber nachdenke, ist das ein fairer Punkt.
Wayne Molina