it-swarm.dev

Welche beliebten "Best Practices" sind nicht immer die besten und warum?

"Best Practices" gibt es überall in unserer Branche. A Google-Suche nach "Best Practices für die Codierung" liefert fast 1,5 Millionen Ergebnisse. Die Idee scheint vielen Trost zu bringen; Folgen Sie einfach den Anweisungen, und alles wird gut.

Wenn ich zum Beispiel über ein Best Practice - lese, habe ich kürzlich mehrere in Clean Code durchgelesen - ich werde nervös. Bedeutet das, dass ich immer diese Praxis anwenden sollte? Gibt es Bedingungen? Gibt es Situationen, in denen nicht eine gute Praxis sein könnte? Wie kann ich sicher wissen, bis ich mehr über das Problem erfahren habe?

Einige der in Clean Code erwähnten Praktiken stimmten nicht mit mir überein, aber ich bin mir ehrlich gesagt nicht sicher, ob das daran liegt, dass sie möglicherweise schlecht sind, oder ob das nur meine persönliche Voreingenommenheit ist. Ich weiß, dass viele prominente Leute in der Technologiebranche zu denken scheinen, dass es gibt keine Best Practices , also bringen mich zumindest meine nagenden Zweifel in gute Gesellschaft.

Die Anzahl der Best Practices, über die ich gelesen habe, ist einfach zu zahlreich, um sie hier aufzulisten oder einzelne Fragen zu stellen. Daher möchte ich dies als allgemeine Frage formulieren:

Welche Codierungspraktiken, die im Volksmund als "Best Practices" bezeichnet werden, können unter bestimmten Umständen nicht optimal oder sogar schädlich sein? Was sind diese Umstände und warum machen sie die Praxis zu einer schlechten?

Ich würde lieber von konkreten Beispielen und Erfahrungen hören.

100
Steven Evers

Ich denke, Sie haben mit dieser Aussage den Nagel auf den Kopf getroffen

Ich würde es hassen, Dinge zum Nennwert zu nehmen und nicht kritisch darüber nachzudenken

Ich ignoriere fast alle Best Practices, wenn es keine Erklärung dafür gibt, warum es sie gibt

Raymond Chen bringt es am besten in dieser Artikel , wenn er sagt

Guter Rat kommt mit einer Begründung, damit Sie erkennen können, wann es zu einem schlechten Rat wird. Wenn Sie nicht verstehen, warum etwas getan werden sollte, sind Sie in die Falle der Frachtkultprogrammierung geraten, und Sie werden es auch dann tun, wenn es nicht mehr notwendig ist oder sogar schädlich wird.

125
Conrad Frix

Könnte das auch in den Ring werfen:

Premature optimization is the root of all evil.

Nein, das ist es nicht.

Das vollständige Zitat:

"Wir sollten kleine Wirkungsgrade vergessen, etwa in 97% der Fälle: Vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen bei diesen kritischen 3% nicht verpassen."

Dies bedeutet, dass Sie während Ihres gesamten Entwurfsprozesses von spezifischen strategischen Leistungsverbesserungen profitieren. Dies bedeutet, dass Sie Datenstrukturen und Algorithmen verwenden, die mit den Leistungszielen übereinstimmen . Dies bedeutet, dass Sie sich der Entwurfsüberlegungen bewusst sind, die sich auf die Leistung auswirken. Dies bedeutet aber auch, dass Sie nicht leichtfertig optimieren, wenn Sie dies tun. Dies führt zu geringfügigen Gewinnen auf Kosten der Wartbarkeit.

Anwendungen müssen gut strukturiert sein, damit sie am Ende nicht herunterfallen, wenn Sie sie ein wenig belasten und sie dann neu schreiben. Die Gefahr mit dem abgekürzten Zitat besteht darin, dass Entwickler es allzu oft als Ausrede benutzen, um erst am Ende über die Leistung nachzudenken, wenn es möglicherweise zu spät ist, etwas dagegen zu unternehmen. Es ist besser, von Anfang an eine gute Leistung zu erzielen, vorausgesetzt, Sie konzentrieren sich nicht auf Kleinigkeiten.

Angenommen, Sie erstellen eine Echtzeitanwendung auf einem eingebetteten System. Sie wählen Python als Programmiersprache, weil "Vorzeitige Optimierung die Wurzel allen Übels ist". Jetzt habe ich nichts gegen Python, aber es ist eine interpretierte Sprache. Wenn die Verarbeitungsleistung begrenzt ist und ein bestimmter Arbeitsaufwand in Echtzeit oder nahezu in Echtzeit erledigt werden muss und Sie eine Sprache auswählen, die mehr Verarbeitungsleistung für die Arbeit erfordert als Sie haben, sind Sie königlich geschraubt, weil Sie jetzt mit einer fähigen Sprache neu beginnen müssen.

95
Robert Harvey

Eine Rückgabe pro Funktion/Methode.

94
iMacUwhAK

Rad nicht neu erfinden ist ein weit verbreitetes Dogma. Die Idee ist, dass Sie eine geeignete Lösung verwenden, anstatt eine eigene zu erstellen. Zusätzlich zum Einsparungsaufwand ist die vorhandene Lösung wahrscheinlich besser implementiert (fehlerfrei, effizient, getestet) als das, was Sie sich ursprünglich einfallen lassen würden. So weit, ist es gut.

Das Problem ist, dass es selten eine 100% geeignete Lösung gibt. Möglicherweise existiert eine zu 80% geeignete Lösung, deren Verwendung wahrscheinlich in Ordnung ist. Aber wie wäre es mit 60% geeignet? 40%? Wo ziehst du die Grenze? Wenn Sie die Grenze nicht ziehen, können Sie am Ende eine aufgeblähte Bibliothek in Ihr Projekt integrieren, weil Sie 10% der Funktionen verwenden - nur weil Sie vermeiden möchten, das Rad neu zu erfinden.

Wenn Sie das Rad neu erfinden, erhalten Sie genau das, was Sie wollen. Sie werden auch lernen, wie man Räder herstellt. Lernen durch Handeln sollte nicht unterschätzt werden. Und am Ende kann ein benutzerdefiniertes Rad besser sein als ein handelsübliches generisches Rad.

87
Joonas Pulakka

"Unit Test Everything."

Ich habe oft gehört, dass jeder Code Unit-Tests haben sollte, ein Punkt, mit dem ich nicht einverstanden bin. Wenn Sie einen Test für eine Methode haben, muss jede Änderung an der Ausgabe oder Struktur dieser Methode zweimal vorgenommen werden (einmal im Code, einmal im Test).

Daher sollten Unit-Tests meiner Meinung nach proportional zur strukturellen Stabilität des Codes sein. Wenn ich ein geschichtetes System von unten nach oben schreibe, werden auf meiner Datenzugriffsschicht Tests im Wazoo durchgeführt. Meine Geschäftslogikschicht wird ziemlich gut getestet, meine Präsentationsschicht wird einige Tests haben und meine Ansichten werden wenig bis gar keine Tests haben.

78
Fishtoaster

Immer Programm zu Schnittstellen.

Manchmal gibt es nur eine Implementierung. Wenn wir den Prozess des Extrahierens einer Schnittstelle bis zu dem Zeitpunkt verzögern, an dem wir die Notwendigkeit dafür erkennen, werden wir häufig feststellen, dass dies nicht erforderlich ist.

57
Eric Wilson

Verwenden Sie nichts Open Source (oder Nicht-Microsoft für Sie .NET-Entwickler)

Wenn Microsoft es nicht entwickelt hat, verwenden wir es hier nicht. Möchten Sie ORM - EF verwenden, möchten Sie IOC - Unity, möchten Sie protokollieren - Enterprise Logging Application Block. Es gibt so viele bessere Bibliotheken - aber ich bin immer nicht in der Lage, über das Dollar-Menü zu bestellen Ich schwöre jedes Mal, wenn ich Microsoft Best Practices höre, denke ich "McDonald's Nutritional Guidelines". Sicher, Sie werden wahrscheinlich leben, wenn Sie sie befolgen, aber Sie werden auch unterernährt und übergewichtig sein.

  • Beachten Sie, dass dies möglicherweise nicht Ihre Best Practice ist, aber es ist eine übliche, die fast überall befolgt wird, wo ich gearbeitet habe.
46
Watson

Objektorientierung

Es gibt die Annahme, nur weil Code "objektorientiert" ist, ist es magisch gut. Daher werden die Funktionen weiterhin in Klassen und Methoden eingeteilt, um objektorientiert zu sein.

40

Der gesamte Code sollte kommentiert werden.

Nein, das sollte nicht sein. Manchmal haben Sie offensichtlichen Code, zum Beispiel sollten Setter nicht kommentiert werden, bis sie etwas Besonderes tun. Warum sollte ich das auch kommentieren:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);
35
Vladimir Ivanov

Methoden, insbesondere Scrum. Ich kann kein ernstes Gesicht behalten, wenn ich höre, dass Erwachsene den Ausdruck "Scrum Master" verwenden. Ich habe es so satt zu hören, wie Entwickler protestieren, dass ein Aspekt von Methodology X nicht für ihr Unternehmen funktioniert, nur um von Guru So-and-So zu erfahren, dass der Grund, warum es nicht funktioniert, darin besteht, dass sie tatsächlich keine wahren Praktiker sind of Methodology X. "Scrum härter, du musst, mein Padawan-Lernender!"

Es gibt Nuggets von Weisheit in agilen Methoden - viele von ihnen -, aber sie sind oft in so viel Mist eingebettet, dass ich meinen Würgereflex nicht bekämpfen kann. Nehmen Sie dieses Bit von Wikipedia-Scrum-Seite :

In Scrum sind eine Reihe von Rollen definiert. Alle Rollen fallen in zwei unterschiedliche Gruppen - Schweine und Hühner - basierend auf der Art ihrer Beteiligung am Entwicklungsprozess.

"Ja wirklich?" Schweine und Hühner, sagst du? Faszinierend! Ich kann es kaum erwarten, dies meinem Chef vorzulegen ...

32
evadeflow

Objektrelationale Zuordnung ... http://en.wikipedia.org/wiki/Object-relational_mapping

Ich möchte niemals von meinen Daten abstrahiert werden, noch möchte ich diese präzise Kontrolle und Optimierung verlieren. Meine Erfahrung mit diesen Systemen war äußerst schlecht ... Die von diesen Abstraktionsschichten erzeugten Abfragen sind noch schlimmer als die, die ich beim Off-Shoring gesehen habe.

25
Fosco

Schreiben von Funktionsnamen, als wären sie englische Sätze:

Draw_Foo()
Write_Foo()
Create_Foo()

usw. Das mag gut aussehen, aber es ist ein Schmerz, wenn Sie eine API lernen. Wie viel einfacher ist es, einen Index nach "Alles, was mit Foo beginnt" zu durchsuchen?

Foo_Draw()
Foo_Write()
Foo_Create()

usw.

22
Colen

YAGNI

( Du wirst es nicht brauchen )

Dieser Ansatz hat mich Stunden und Stunden gekostet, als ich Funktionen in einer vorhandenen Codebasis implementieren musste, wobei diese Funktionen zuvor sorgfältig geplant worden wären.

Meine Ideen wurden oft wegen YAGNI abgelehnt, und meistens musste jemand später für diese Entscheidung bezahlen.

(Natürlich könnte man argumentieren, dass eine gut gestaltete Codebasis auch das spätere Hinzufügen von Funktionen ermöglichen würde, aber die Realität sieht anders aus.)

22

MVC - Ich finde oft, dass es bei der Integration vieler Webdesign-Probleme in den MVC-Ansatz mehr darum geht, ein Framework (Rails usw.) glücklich zu machen, als um Einfachheit oder Struktur. MVC ist ein Favorit von "Architekturastronauten", die übermäßiges Gerüst gegenüber Einfachheit zu schätzen scheinen. ymmv.

klassenbasiert OO - meiner Meinung nach fördert komplexe Strukturen veränderlichen Zustands. Die einzigen zwingenden Fälle, die ich für klassenbasierte OO im Laufe der Jahre gefunden habe, sind die kitschige "Form-> Rechteck-> Quadrat" -Beispiele, die Kapitel 1 eines beliebigen Buches bilden OO)

22
Brad Clawsie

Für SQL

  1. Verwenden Sie keine Trigger
  2. Verstecken Sie Tabellen immer hinter Ansichten

In Ordnung:

  1. Sie sind eine Funktion, die ihren Platz hat. Sie haben mehrere Aktualisierungspfade zu einer Tabelle oder benötigen eine 100% ige Prüfung?

  2. Warum nur? Ich würde, wenn ich umgestalten würde, um einen Vertrag aufrechtzuerhalten, aber nicht, wenn ich gelesen habe, dass Leute die Ansicht ändern, um sie an Tabellenänderungen anzupassen

Bearbeiten:

Nummer 3: Vermeiden * mit EXISTS. Versuchen Sie 1/0. Es klappt. Die Spaltenliste wird nicht gemäß SQL-Standard ausgewertet. Seite 191

20
gbn

Designmuster meistens. Sie werden überbeansprucht und unterbeansprucht.

20
Geek

Das Prinzip der Einzelverantwortung

("Jede Klasse sollte nur eine einzige Verantwortung haben; mit anderen Worten, jede Klasse sollte einen und nur einen Grund haben, sich zu ändern")

Ich stimme dir nicht zu. Ich denke, eine Methode sollte nur einen Grund zur Änderung haben, und alle Methoden in einer Klasse sollten eine logische Beziehung zueinander haben, aber die Klasse selbst könnte tatsächlich do mehrere (verwandte) Dinge.

Nach meiner Erfahrung wird dieses Prinzip zu oft übermäßig eifrig angewendet, und Sie erhalten am Ende viele winzige Ein-Methoden-Klassen. Beide agilen Läden, in denen ich gearbeitet habe, haben dies getan.

Stellen Sie sich vor, die Entwickler der .Net-API hätten diese Art von Mentalität: anstelle von List.Sort (), List.Reverse (), List.Find () usw.) habe ListSorter-, ListReverser- und ListSearcher-Klassen!

Anstatt mehr gegen die SRP zu argumentieren (was theoretisch selbst nicht schrecklich ist), werde ich einige meiner langatmigen anekdotischen Erfahrungen teilen:


An einer Stelle, an der ich gearbeitet habe, habe ich ein sehr einfaches max flow solver geschrieben, das aus fünf Klassen bestand: einem Knoten, einem Diagramm, einem Diagrammersteller, einem Diagrammlöser und einer Klasse zur Verwendung des Diagramms -Ersteller/Löser, um ein reales Problem zu lösen. Keiner war besonders komplex oder lang (der Löser war mit ~ 150 Zeilen bei weitem der längste). Es wurde jedoch entschieden, dass die Klassen zu viele "Verantwortlichkeiten" hatten, und so begannen meine Mitarbeiter, den Code umzugestalten. Als sie fertig waren, waren meine 5 Klassen auf 25 Klassen erweitert worden, deren gesamte Codezeile mehr als dreimal so groß war wie ursprünglich. Der Fluss des Codes war nicht mehr offensichtlich, noch war der Zweck der neuen Unit-Tests; Es fiel mir jetzt schwer herauszufinden, was mein eigener Code tat.


Am selben Ort hatte fast jede Klasse nur eine einzige Methode (ihre einzige "Verantwortung"). Es war nahezu unmöglich, dem Ablauf innerhalb des Programms zu folgen, und die meisten Unit-Tests bestanden darin, zu testen, ob diese Klasse Code von einer anderen Klasse aufgerufen wurde, die beide ihren Zweck hatten Ebenso ein Rätsel für mich. Es gab buchstäblich Hunderte von Klassen, in denen es nur Dutzende (IMO) hätte geben sollen. Jede Klasse hat nur eine "Sache" gemacht, aber selbst mit Namenskonventionen wie "AdminUserCreationAttemptorFactory" War es schwierig, die Beziehung zwischen Klassen zu erkennen.


An einem anderen Ort (der auch die Mentalität Klassen sollten nur eine haben hatten) versuchten wir, eine Methode zu optimieren, die während einer bestimmten Operation 95% der Zeit in Anspruch nahm. Nachdem ich es (ziemlich dumm) ein wenig optimiert hatte, richtete ich meine Aufmerksamkeit auf warum es wurde eine Bajillion Mal genannt. Es wurde in einer Schleife in einer Klasse aufgerufen ... deren Methode in einer Schleife in einer anderen Klasse aufgerufen wurde ... die auch in einer Schleife aufgerufen wurde.

Insgesamt gab es fünf Ebenen von Loops, die auf 13 Klassen verteilt waren (ernsthaft). Was eine Klasse tatsächlich tat, war unmöglich zu bestimmen, indem man es sich ansah - man musste einen mentalen Graphen darüber skizzieren, welche Methoden sie nannte und welche Methoden diese Methoden nannten und so weiter. Wenn alles in einer Methode zusammengefasst worden wäre, wäre es nur etwa 70 Zeilen lang gewesen, wenn unsere Problemmethode in fünf sofort offensichtlichen Ebenen von Schleifen verschachtelt gewesen wäre.

Mein Antrag, diese 13 Klassen in eine Klasse umzuwandeln, wurde abgelehnt.

Nun, da Sie Clean Code erwähnt haben, obwohl es einige gute Ideen enthält, denke ich, dass seine Besessenheit, alle Methoden in Untermethoden und diejenigen in Untermethoden usw. umzugestalten, viel zu weit gegangen ist. Anstelle von ein paar Zehn-Zeilen-Methoden sollten Sie zwanzig (angeblich gut benannte) Einzeiler bevorzugen. Offensichtlich denkt jemand, dass es sauber ist, aber für mich scheint es viel schlimmer als die Originalversion.

Auch das Ersetzen einfacher elementarer Dinge wie

0 == memberArray.length

innerhalb einer Klasse mit einem Aufruf der eigenen Methode der Klasse wie z

isEmpty()

ist meiner Meinung nach eine fragwürdige "Verbesserung". Addition: Der Unterschied besteht darin, dass die erste Prüfung genau das tut, was sie sagt: prüft, ob die Array-Länge 0 ist. Ok, isEmpty() überprüft möglicherweise auch die Array-Länge. Es könnte aber auch so implementiert werden:

return null != memberArray ? 0 == memberArray.length : true;

Das heißt, es enthält eine implizite Nullprüfung! Dies mag für eine öffentliche Methode ein gutes Verhalten sein - wenn das Array null ist, ist sicherlich etwas leer -, aber wenn es um Klasseninternale geht, ist dies nicht so gut. Während die Kapselung nach außen ein Muss ist, müssen die Interna der Klasse genau wissen, was in der Klasse vor sich geht. Sie können die Klasse nicht aus sich selbst kapseln . Explizit ist besser als implizit.


Dies bedeutet nicht, dass es nicht gut ist, lange Methoden oder logische Vergleiche aufzubrechen. Natürlich ist es das, aber bis zu welchem ​​Grad - wo der Sweet Spot ist - ist offensichtlich eine Frage des Geschmacks. Das Aufbrechen einer langen Methode führt zu mehr Methoden, und das ist nicht kostenlos. Sie müssen im Quellcode herumspringen, um zu sehen, was wirklich los ist, wenn Sie auf einen Blick sehen können, ob all diese Dinge in einer einzigen Methode enthalten sind.

Ich würde sogar so weit gehen zu sagen, dass in einigen Fällen eine 1-Zeilen-Methode zu kurz ist, um eine Methode zu verdienen.

14
Joonas Pulakka

"Sei liberal mit Kommentaren"

Kommentare sind definitiv eine gute Sache, aber zu viele sind genauso schlecht, wenn nicht schlechter als nicht genug. Warum? Nun, Leute neigen dazu, Kommentare auszuschalten, wenn sie zu viele unnötige sehen. Ich sage nicht, dass Sie perfekt selbstdokumentierenden Code haben können, aber es ist vorzuziehen, Code zu verwenden, der zur Erklärung Kommentare benötigt.

13
Jason Baker

GoTo als schädlich angesehen

Wenn Sie eine Zustandsmaschine implementieren, kann eine GOTO-Anweisung sinnvoller sein (Lesbarkeit und effizienter Code) als ein Ansatz der "strukturierten Programmierung". Es hat einige Mitarbeiter wirklich beunruhigt, als der erste Code, den ich in einem neuen Job schrieb, nicht nur eine, sondern mehrere goto-Anweisungen enthielt. Zum Glück waren sie intelligent genug, um zu erkennen, dass dies in diesem speziellen Fall tatsächlich die beste Lösung war.

Jede "Best Practice", die keine vernünftigen und dokumentierten Ausnahmen von ihren Regeln zulässt, ist einfach beängstigend.

12
MZB

Die Opfer, die wir bringen, um Code testbar zu machen

Ich springe durch viele Rahmen, um meinen Code testbar zu machen, aber ich gebe nicht vor, dass ich es nicht tun würde, wenn ich die Wahl hätte. Ich höre jedoch oft Leute, die die Idee vertreten, dass dies "Best Practices" sind. Diese Praktiken umfassen (geschrieben in der Sprache von .Net, gilt aber auch für andere Sprachen):

  • Erstellen einer Schnittstelle für alle Klassen. Dies verdoppelt die Anzahl der Klassen ( Dateien) zu verarbeiten und Code zu duplizieren. Ja, Schnittstellenprogrammierung ist gut, aber dafür sind die öffentlichen/privaten Spezifizierer gedacht.
  • Jede Klasse, die beim Start nicht instanziiert wurde, benötigt eine Factory. Natürlich ist new MyClass() viel einfacher als das Schreiben einer Factory, aber jetzt die Methode, die erstellt es kann nicht isoliert getestet werden. Ohne diese Tatsache würde ich nur 1/20 der Anzahl der Fabrikklassen machen, die ich jetzt mache.
  • Machen Sie jede Klasse öffentlich, , was den Zweck zunichte macht, überhaupt Zugriffsspezifizierer für Klassen zu haben. Auf nicht öffentliche Klassen kann jedoch nicht von anderen Projekten aus zugegriffen (und somit getestet) werden. Die einzige andere Option besteht darin, den gesamten Testcode in dasselbe Projekt zu verschieben (und ihn daher mit dem Endprodukt freizugeben).
  • Abhängigkeitsinjektion. Es ist eindeutig mehr Arbeit, alle andere Klasse zu geben, für die ich ein Feld und einen Konstruktorparameter verwende als sie nur zu erschaffen, wenn ich sie brauche; aber dann kann ich diese Klasse nicht mehr isoliert testen.
  • Das Prinzip der Einzelverantwortung , das mir so viele Kopfschmerzen bereitet hat, dass ich es auf seine eigene Antwort verschoben habe.

Was könnten wir also tun, um dies zu beheben? Wir brauchen eine drastische Änderung in der Spracharchitektur:

  • Wir würden die Fähigkeit brauchen, Klassen zu verspotten
  • Wir benötigen die Fähigkeit, private Methoden interner Klassen aus einem anderen Projekt zu testen (Dies scheint eine Sicherheitslücke zu sein, aber ich sehe kein Problem, wenn der Testteilnehmer gezwungen ist, seine Testerklassen zu benennen.) .
  • Die Abhängigkeitsinjektion (oder der Servicestandort) sowie etwas, das unserem bestehenden Factory-Muster entspricht, müsste ein Kern Teil der Sprache sein.

Kurz gesagt, wir brauchen eine Sprache, die von Grund auf unter Berücksichtigung der Testbarkeit entwickelt wurde .

Aufteilen von Anwendungen in Ebenen; Datenschicht, Geschäftsschicht, UI-Schicht

Der Hauptgrund, warum ich das nicht mag, ist, dass die meisten Orte, die dieser Methode folgen, sehr spröde Frameworks verwenden, um dies zu erreichen. I.E. UI Layer ist handcodiert, um mit Business Layer-Objekten umzugehen, Business Layer-Objekte sind handcodiert, um mit Geschäftsregeln und Datenbanken umzugehen, Datenbank ist SQL und ist bereits ziemlich spröde und wird von der "DBA" -Gruppe verwaltet, die Änderungen nicht mag.

Warum ist das so schlimm? Die häufigste Erweiterungsanforderung lautet wahrscheinlich "Ich benötige ein Feld auf Bildschirm X mit Y." Knall! Sie haben nur eine neue Funktion, die sich auf jede einzelne Ebene auswirkt, und wenn Sie Ebenen mit verschiedenen Programmierern trennen, wurde dies für eine sehr einfache Änderung zu einem großen Problem, an dem mehrere Personen und Gruppen beteiligt waren.

Außerdem weiß ich nicht, wie oft ich in solchen Argumenten gestritten habe. "Das Namensfeld ist auf eine maximale Länge von 30 begrenzt. Handelt es sich um ein Problem mit der Benutzeroberfläche, der Geschäftsschicht oder der Datenschicht?" Und es gibt hundert Argumente und keine richtige Antwort. Die Antwort ist dieselbe, sie betrifft alle Ebenen. Sie möchten die Benutzeroberfläche nicht dumm machen und müssen alle Ebenen durchlaufen und in der Datenbank fehlschlagen, nur damit der Benutzer feststellt, dass sein Eintrag zu lang ist. Wenn Sie es ändern, wirkt es sich auf alle Ebenen usw. aus.

Die "Schichten" neigen auch dazu zu lecken; Wenn eine Ebene physisch durch Prozess-/Maschinengrenzen getrennt ist (z. B. Web-Benutzeroberfläche und Business-Backend-Logik), werden die Regeln dupliziert, damit alles einigermaßen gut funktioniert. Das heißt, Einige Geschäftslogiken landen in der Benutzeroberfläche, obwohl es sich um eine "Geschäftsregel" handelt, da der Benutzer die Benutzeroberfläche benötigt, um reagieren zu können.

Wenn das verwendete Framework oder die verwendete Architektur gegenüber kleinen Änderungen und Leckagen, d. H. Basierend auf Metadaten, stabil ist und über alle Ebenen dynamisch angepasst wird, kann dies weniger schmerzhaft sein. Bei den meisten Frameworks ist dies jedoch ein königlicher Schmerz, der für jede kleine Änderung Änderungen an der Benutzeroberfläche, der Geschäftsschicht und der Datenbank erfordert und mehr Arbeit und weniger Hilfe verursacht, als die Technik produzieren soll.

Ich werde wahrscheinlich dafür zugeschlagen, aber da ist es :)

10
Jay

JavaBeans

Die Verwendung von JavaBeans in Java. Siehe meine Frage Warum sollte ich keine unveränderlichen POJOs anstelle von JavaBeans verwenden? auf StackOverflow.

9
Jonas

User Stories/Use Cases/Personas

Ich verstehe die Notwendigkeit für diese, wenn Sie für eine Branche programmieren, mit der Sie nicht vertraut sind, aber ich denke, dass sie, wenn sie in vollem Umfang implementiert werden, zu korporativ werden und Zeitverschwendung werden.

7
riwalk

80 Zeichen/Zeilenlimits sind dumm

Ich verstehe, dass einige Kompromisse eingegangen werden müssen, um dem Tempo des langsamsten Läufers auf der GUI-Seite zu entsprechen (Einschränkungen der Bildschirmauflösung usw.), aber warum gilt diese Regel für die Code-Formatierung?

Siehe ... Es gab diese kleine Erfindung namens horizontale Bildlaufleiste, die erstellt wurde, um den virtuellen Bildschirmbereich außerhalb der Pixelgrenze ganz rechts zu verwalten. Warum verwenden Entwickler, die es geschafft haben, großartige produktivitätssteigernde Tools wie Syntaxhervorhebung und automatische Vervollständigung zu erstellen, diese nicht?

Sicher, es gibt CLI-Editoren, die von * nix-Dinosauriern religiös verwendet werden und den müden alten Einschränkungen ihrer VT220-Terminals folgen, aber warum halten wir alle den gleichen Standard?

Ich sage, schraube die 80 Zeichen Grenze. Wenn die Dinosaurier episch genug sind, um den ganzen Tag auf Emacs/Vim zu hacken, warum sollte der dann nicht in der Lage sein, eine Erweiterung zu erstellen, die automatisch Zeilen umschließt oder ihren CLI-IDEs horizontale Bildlauffunktionen verleiht?

1920 x 1080 Pixel-Monitore werden irgendwann zur Norm und Entwickler auf der ganzen Welt leben immer noch unter denselben Einschränkungen, ohne dass dies einen Einfluss darauf hat. Dies wurde ihnen von ihren Ältesten gesagt, als sie gerade mit dem Programmieren begannen.

80 Zeichenlimits sind nicht eine bewährte Methode, aber eine Nischenpraxis für eine sehr kleine Minderheit von Programmierern und sollten als solche behandelt werden.

Edit :

Es ist verständlich, dass viele Entwickler die horizontale Bildlaufleiste nicht mögen, weil sie eine Mausbewegung erfordert. Warum also nicht die Spaltenbreitenbeschränkung für diejenigen von uns, die moderne Displays verwenden, auf eine höhere Zahl (als 80) erhöhen?.

Als 800x600-Computermonitore für die meisten Benutzer zur Norm wurden, erhöhten Webentwickler ihre Website-Breite, um die Mehrheit zu berücksichtigen ... Warum können Entwickler nicht dasselbe tun?.

7
Evan Plaice

Messen, Messen, Messen

Also gut, messen Sie weg, aber für isolieren Leistungsfehler funktioniert das Messen ungefähr so ​​gut wie die sukzessive Beseitigung. Hier ist die Methode, die ich benutze.

Ich habe versucht, die Quelle des Maßes "Weisheit" aufzuspüren. Jemand mit einer ausreichend großen Seifenkiste hat es gesagt, und jetzt reist es.

5
Mike Dunlavey

Verwenden Sie Singletons

Wenn Sie nur eine Instanz von etwas haben sollten. Ich kann nicht nicht einverstanden mehr. Verwenden Sie niemals einen Singleton und weisen Sie ihn nur einmal zu und übergeben Sie den Zeiger/das Objekt/die Referenz nach Bedarf. Es gibt absolut keinen Grund, dies nicht zu tun.

5
user2528

Mein Lehrer verlangt, dass ich alle meine Bezeichner (ohne Konstanten) mit Kleinbuchstaben beginne, z. myVariable.

Ich weiß, es scheint eine Kleinigkeit zu sein, aber viele Programmiersprachen erfordern Variablen, um mit Großbuchstaben zu beginnen. Ich schätze Konsistenz, daher ist es meine Gewohnheit, alles mit Großbuchstaben zu beginnen.

5
Maxpm

Verwenden von unsigned int als Iterator

Wann werden sie erfahren, dass die Verwendung von signiertem int viel sicherer und weniger fehleranfällig ist? Warum ist es so wichtig, dass der Array-Index nur eine positive Zahl sein kann, dass jeder froh ist, die Tatsache zu übersehen, dass 4 - 5 4294967295 ist?

5
AareP

Methoden sollten nicht länger als ein einzelner Bildschirm sein

Ich stimme dem Prinzip der Einzelverantwortung voll und ganz zu, aber warum verstehen die Leute es als "eine Funktion/Methode kann nicht mehr als eine Einzelverantwortung auf der feinsten Ebene der logischen Granularität haben"?

Die Idee ist einfach. Eine Funktion/Methode sollte eine Aufgabe erfüllen. Wenn ein Teil dieser Funktion/Methode an anderer Stelle verwendet werden kann, zerlegen Sie ihn in eine eigene Funktion/Methode. Wenn es an anderer Stelle im Projekt verwendet werden könnte, verschieben Sie es in eine eigene Klasse oder eine Utility-Klasse und machen Sie es intern zugänglich.

Eine Klasse mit 27 Hilfsmethoden zu haben, die nur einmal im Code aufgerufen werden, ist dumm, Platzverschwendung, eine unnötige Erhöhung der Komplexität und eine massive Zeitsenke. Es klingt eher nach einer guten Regel für Leute, die beschäftigt sein wollen, Code umzugestalten, aber nicht viel produzieren.

Hier ist meine Regel ...

Schreibe Funktionen/Methoden, um etwas zu erreichen

Wenn Sie dabei sind, Code zu kopieren/einzufügen, fragen Sie sich, ob es besser ist, eine Funktion/Methode für diesen Code zu erstellen. Wenn eine Funktion/Methode in einer anderen Funktion/Methode nur einmal aufgerufen wird, ist es wirklich sinnvoll, sie überhaupt zu haben (wird sie in Zukunft häufiger aufgerufen). Ist es wertvoll, während des Debuggens weitere Sprünge in/aus Funktionen/Methoden hinzuzufügen (dh macht der hinzugefügte Sprung das Debuggen einfacher oder schwieriger)?

Ich stimme voll und ganz zu, dass Funktionen/Methoden mit mehr als 200 Zeilen überprüft werden müssen, aber einige Funktionen erfüllen nur eine Aufgabe in so vielen Zeilen und enthalten keine nützlichen Teile, die für den Rest des Projekts abstrahiert/verwendet werden können.

Ich betrachte es aus der Perspektive eines API-Entwicklers ... Wenn ein neuer Benutzer das Klassendiagramm Ihres Codes betrachten würde, wie viele Teile dieses Diagramms wären im gesamten Projekt sinnvoll und wie viele würden nur als existieren Helfer zu anderen projektinternen Teilen.

Wenn ich zwischen zwei Programmierern wählen würde: Der erste hat die Tendenz, Funktionen/Methoden zu schreiben, die versuchen, zu viel zu tun; Der zweite Teil bricht jeden Teil jeder Funktion/Methode auf ein Höchstmaß an Granularität. Ich würde die ersten Hände runter wählen. Der erste würde mehr erreichen (dh mehr Fleisch der Anwendung schreiben), sein Code wäre einfacher zu debuggen (aufgrund weniger Sprünge in/aus Funktionen/Methoden während des Debuggens) und er würde weniger Zeit damit verschwenden, die Arbeit zu perfektionieren Der Code sieht aus und perfektioniert nicht, wie der Code funktioniert.

Begrenzen Sie unnötige Abstraktionen und verschmutzen Sie die automatische Vervollständigung nicht.

4
Evan Plaice

Absolutistisch, streng, Kapselung

Ich stimme der Kapselung größtenteils zu, aber es war ein echter Befreier, diese Regel vorübergehend zu brechen, um einen prozeduralen Code in OOP unter Verwendung des Array to Object Refactoring . ( Ich brauchte ein bisschen Push, um mich ein bisschen zu lockern. Danke, Martin Fowler)

  • Array

    ->

  • neue Klasse mit Array als public Eigenschaft

    ->

  • client-Code durchgehen/Accessoren hinzufügen

    ->

  • nur dann kapseln Sie es und machen Sie es privat/geschützt

2
JW01

Über Verallgemeinerung.

Der quadratische Block passt NICHT in das Kreisloch!

1
PMV

Ich kann mir nur vorstellen, Java if Anweisungen wie folgt zu formatieren:

if (condition) ...

anstatt

if(condition) ...

Zum größten Teil habe ich festgestellt, dass Best Practices die besten sind, und alle anfänglichen Vorbehalte, die ich bei ihnen habe, werden häufig verlegt oder durch wichtigere Bedenken außer Kraft gesetzt.

1
Armand

"Wenn es nicht kaputt ist, reparieren Sie es nicht". Code ist immer kaputt. Der Grund, warum niemand dem ursprünglichen Entwickler davon erzählt, ist, dass er es tut

  1. denke, es ist ihre eigene Schuld,
  2. ich weiß nicht, wen ich kontaktieren soll.
  3. kann nicht durch Unterstützung kommen, um mit einem "Technikfreak" zu sprechen,
  4. kann nicht gestört werden, oder
  5. ich weiß nicht, wie ich das Problem detailliert beschreiben soll.
1
l0b0

Bevorzugen Sie immer lange, explizite, variable und routinemäßige Namen gegenüber der verkürzten Form

b. Bevorzugung Authentifizierung gegenüber AuthN

Dies hat mich gebissen , als die MS-Dateipfade so lang wurden, dass meine Subversion-Arbeitskopie nicht auf meinen PC geladen werden konnte.

Siehe: https://stackoverflow.com/questions/3282303/my-choice-of-class-names-is-hampered-by-windows-xp-max-path-length-issues-with-sv

1
JW01

Ich neige dazu, fast alle Best Practices zu ignorieren, wenn ich ein relativ kleines, einmaliges Projekt mache, wie das Schreiben eines Parsers, der zum Migrieren von Dateien erforderlich ist. Wenn alles, was ich brauche, das Ergebnis ist, ist mir Lesbarkeit, Skalierbarkeit, Wartbarkeit usw. egal.

1
user281377

Threading ist die Antwort auf alle Leistungsprobleme

Stimme dem aus vielen Gründen nicht zu.

  • Im Allgemeinen steigern Indizierung und zeitliches Caching die Leistung erheblich. Natürlich müssen Sie möglicherweise tatsächlich "schmutzige Flaggen" verwenden. Machen Sie Ihr Design alles chaotisch und so.

  • Probleme, die durch Multithreading-Übergewicht entstehen, sind zeit- und geldmäßig von Vorteil.

  • Was uns die Multi-Core-Technologie wirklich gebracht hat, ist ein besseres Multitasking (einige Anwendungen werden genauso schnell ausgeführt wie eine). Die Verwendung von geschickt geschriebenen Multithreading-Programmen ist nur ein Nebeneffekt.

0
AareP

CONTINUE STATEMENT IS BAD

Ich werde hier auf die C++ - Codierungsstandards für Joint Strike Fighter-Luftfahrzeuge verweisen:

AV-Regel 190 (MISRA-Regel 57) Die Anweisung continue darf nicht verwendet werden.

und ein Professor von mir:

"THE CONTINUE STATEMENT IS BAD"

Ihre Logik ist, dass es den Kontrollfluss stört und den Code weniger lesbar macht. Die Verwendung verschachtelter if - Anweisungen ist ein sauberer Ansatz.

Ich finde das jedoch lesbarer:

 
for(int i = 0; i < CONST_FOO; ++i) {
    if(aTwo[i] == NULL) continue;
    aTwo[i]->DoBar();
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
}
 

Als das:

 
for(int i = 0; i < CONST_FOO; ++i) {
    if(aTwo[i] != NULL) {
        aTwo[i]->DoBar();
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
    }
}
 

Dies ist ein sehr vereinfachtes Beispiel (stellen Sie sich vor, die verschachtelten Ifs gehen weit über eine Ebene hinaus), aber es ähnelt der lächerlichen "Best" -Praxis "nur eine return-Anweisung pro Funktion". Es verhindert, dass der Debugger herumspringt (möglicherweise mehrere Seiten entfernt), weniger Einrückungen führen im Allgemeinen zu leicht lesbarem Code usw.

0
Casey

In JavaScript halten es viele Leute für die beste Vorgehensweise, alle benötigten Semikolons in anderen C-Zweigsprachen zu schreiben (und viele von ihnen haben keine Angst, auf den "Fehler" hinzuweisen, wenn sie Code sehen, der mehr Semikolons enthalten könnte). Ich habe nie einen Bedarf für sie gefunden, ihre Rolle als visueller Marker ist bereits durch Linienverschiebungen ausgefüllt.

Nebenbei bemerkt ist es ein bisschen lustig zu sehen, wie ein Compiler Semikolons benötigt, aber dennoch sicher den Fehler "Fehlendes Semikolon" auslöst. "Wir wissen beide, was Sie schreiben wollten, aber ich muss Ihre Bewerbung ablehnen, weil ich formal nicht zwischen Leerzeichen und Zeilenverschiebungen unterscheiden darf."

Eine Reihe anderer Best Practices im JavaScript/C-Stil sind im Umlauf, aber keine davon kommt dem Hype ohne qualifizierte Argumente nahe.

Bearbeiten: Es ist durchaus möglich, Code ohne Semikolons zu minimieren Closure Compiler fügt sie nach Bedarf ein.

0
aaaaaaaaaaaa

Nun, einer meiner Hot Buttons ist Leistungsanalyse . Leute sagen

Vorzeitige Optimierung ist die Wurzel allen Übels.

Und dann sagen sie, das vollständige Zitat sei:

Wir sollten kleine Wirkungsgrade vergessen, etwa in 97% der Fälle: Vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen bei diesen kritischen 3% nicht verpassen.

Was durchaus Sinn macht, wenn Sie über "Algorithmen" sprechen - clevere akademische Dinge, bei denen 3% des Programms aus zwei Codezeilen bestehen können.

Ich arbeite in 10 ^ 6-Zeilen-Apps mit 10 ^ 5 Methoden in 10 ^ 4 Klassen, die über Jahre von einem Dutzend Programmierern und Testern bearbeitet wurden und zahlreiche Überarbeitungen und Releases durchlaufen, bei denen dieses Zitat überhaupt keine Relevanz hat. Typischerweise sind die Zeitverschwendung einzelne Codezeilen, die "Gelegenheiten" sein können, aber niemand könnte jemals erraten, wo sie sich befinden.

OTOH, die Leute sagen "Profil" oder sie sagen "Maßnahme messen". Also gut. Sie sagen es, aber sie tun es nicht oft. Könnte sein, der Grund, warum sie es nicht tun, ist , dass es nicht sehr gut funktioniert .

Diese Antwort sagt mehr darüber und weist darauf hin, was funktioniert .

0
Mike Dunlavey

Datenbindung

Ich hasse es und liebe es. (Abhängig von der Komplexität des Projekts)

0
Amir Rezaei