Ist es jemals eine gute Idee, Werte in unsere Anwendungen fest zu codieren? Oder ist es immer richtig, diese Wertetypen dynamisch aufzurufen, falls sie geändert werden müssen?

Kommentare

  • Ein Konfigurationsparameter würde Ihnen helfen
  • Sie wissen nie, wann sich der Wert von pi ändern könnte …
  • Mann, ich denke, Leute wie @gabe sind der Grund dafür ist eine “ Regel „. Wenn Sie 3.14 an 20 Stellen in Ihrem Code wiederholen und dann feststellen, dass Sie tatsächlich mehr Genauigkeit benötigen, sind Sie geschraubt. Ich habe ‚ nicht bemerkt, dass dies nicht ‚ nicht offensichtlich war.
  • Das war ein wenig unhöflich, @Bill. @Gabe scherzte eindeutig, aber abgesehen davon ging es um Hardcoding vs. Konfigurationsparameter, bei denen keine konstanten vs. wiederholten magischen Zahlen an mehreren Stellen verwendet wurden.
  • Ja, Hardcoding kann manchmal eine gute Idee sein . Siehe den Wikipedia-Artikel zum “ Softcoding “ Anti-Pattern.

Antwort

Ja, aber machen Sie es offensichtlich .

Führen Sie Folgendes aus:

Variablenname

Keine t

Kommentare

  • Was sauberer ist, diameter = 2 * radius oder diameter = RADIUS_TO_DIAMETER_FACTOR * radius? Es gibt tatsächlich Eckfälle, in denen eine magische Zahl eine bessere Lösung sein kann.
  • Ich kann ‚ nicht zustimmen Diese Antwort reicht aus. Ich neige dazu, Programmieren als Romanautor zu betrachten. Sie erzählen Ihre Geschichte durch den Code, und wenn die Leute die Logik nicht verstehen können, macht dies Ihren Code meiner Meinung nach wertlos. Das ‚ s warum gut durchdachte Namenskonventionen im Wesentlichen der Lesbarkeit dienen. Es gibt auch keinen guten Grund, magische Zahlen zu verwenden. Durch die Verwendung magischer Zahlen entfernen Sie das “ warum “ aus der Gleichung und erschweren das Unterstellen tand. Zum Beispiel: “ Durchmesser = 2 * Radius “ Wofür sind die beiden? Dieser “ Durchmesser = RADIUS_TO_DIAMETER_FACTOR * Radius “ ist viel sinnvoller.
  • Durchmesser = 2 * Radius ist direkt von High School Mathe. Der Grund dafür, dass die “ 2 “ nicht benannt wird, besteht darin, dass eine Änderung der Gesetze von erforderlich wäre, um einen Wert für etwas anderes zu haben Physik oder Mathematik oder beides. (Andererseits ist die Benennung von Pi oder Plancks-Konstante ein guter Schritt für eine einfache Lesbarkeit.)
  • @Joonas: Pfft. Sicher meinst du diameter = radius << 1? Ich nehme an, das könnte auch diameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT sein.
  • wie ‚ um einige diameter = radius.toDiameter()

Antwort

Was ich an diesem Q merkwürdig finde & A ist bisher, dass niemand tatsächlich versucht hat, „Hardcode“ oder, was noch wichtiger ist, die Alternativen klar zu definieren.

tl; dr : Ja, es ist manchmal eine gute Idee, Werte hart zu codieren, aber es gibt keine einfache Regel für wann ; es hängt vollständig vom Kontext ab.

Die Frage beschränkt sich auf Werte , was ich als magische Zahlen bezeichne , aber die Antwort darauf, ob sie eine gute Idee sind oder nicht, hängt davon ab, wofür sie tatsächlich verwendet werden!

Mehrere Beispiele für „hartcodiert“ „Werte sind:

  • Konfigurationswerte

    Ich erschrecke, wenn ich Aussagen sehe wie command.Timeout = 600. Warum 600? Wer hat das entschieden? War es vorher ein Timeout und jemand hat das Timeout als Hack ausgelöst, anstatt das zugrunde liegende Leistungsproblem zu beheben? Oder ist es tatsächlich eine bekannte und dokumentierte Erwartung für die Verarbeitungszeit?

    Dies sollten keine magischen Zahlen oder Konstanten sein, sie sollten in einer Konfigurationsdatei oder Datenbank irgendwo mit einem externalisiert werden aussagekräftiger Name, da ihr optimaler Wert weitgehend oder vollständig von der Umgebung bestimmt wird, in der die Anwendung ausgeführt wird.

  • Mathematische Formeln

    Formeln sind normalerweise ziemlich statisch, so dass die Art der konstanten Werte im Inneren nicht wirklich besonders wichtig ist. Das Volumen einer Pyramide beträgt (1/3) b * h. Interessiert es uns, woher die 1 oder 3 kamen? Nicht wirklich. Ein früherer Kommentator hat zu Recht darauf hingewiesen, dass diameter = radius * 2 wahrscheinlich besser ist als diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR – aber das ist eine falsche Zweiteilung.

    Für diese Art von Szenario sollten Sie eine -Funktion erstellen. Ich muss nicht wissen, wie Sie auf die Formel gekommen sind, aber ich muss immer noch wissen, wofür sie ist. Wenn ich anstelle des oben geschriebenen Unsinns volume = GetVolumeOfPyramid(base, height) schreibe, wird plötzlich alles viel klarer und es ist vollkommen in Ordnung, magische Zahlen in die Funktion (return base * height / 3), weil es offensichtlich ist, dass sie nur ein Teil der Formel sind.

    Der Schlüssel hier ist natürlich kurze und einfache Funktionen. Dies funktioniert nicht für Funktionen mit 10 Argumenten und 30 Berechnungszeilen. Verwenden Sie in diesem Fall die Funktionszusammensetzung oder Konstanten.

  • Domänen- / Geschäftsregeln

    Dies ist immer die Grauzone, da dies davon abhängt, was genau der Wert ist. Meistens sind es diese besonderen magischen Zahlen, die Kandidaten für die Umwandlung in Konstanten sind, da dies das Verständnis des Programms erleichtert, ohne die Programmlogik zu komplizieren. Betrachten Sie den Test if Age < 19 vs. if Age < LegalDrinkingAge; Sie können wahrscheinlich herausfinden, was ohne die Konstante vor sich geht, aber mit der Beschreibung ist es einfacher Titel.

    Diese können auch zu Kandidaten für die Funktionsabstraktion werden, z. B. function isLegalDrinkingAge(age) { return age >= 19 }. Das einzige ist, dass Ihre Geschäftslogik häufig so ist viel komplizierter als das, und es ist möglicherweise nicht sinnvoll, Dutzende von Funktionen mit jeweils 20 bis 30 Parametern zu schreiben. Wenn es keine eindeutige Abstraktion basierend auf Objekten und / oder Funktionen gibt, ist es in Ordnung, auf Konstanten zurückzugreifen.

    Die Einschränkung ist, wenn Sie für die Steuerabteilung arbeiten, wird es wirklich, wirklich, sehr lästig und ehrlich gesagt sinnlos, AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR) zu schreiben. Du wirst das nicht tun t, Sie gehen zu AttachForm("B-46"), weil jeder einzelne Entwickler, der jemals dort gearbeitet hat oder jemals arbeiten wird, wissen wird, dass „B-46“ der Formularcode für einen einzelnen Steuerzahler ist archivieren bla bla bla – die Formularcodes sind Teil der Domäne selbst, sie ändern sich nie, daher sind sie keine wirklich magischen Zahlen.

    Daher müssen Sie Konstanten in der Geschäftslogik sparsam verwenden. Grundsätzlich muss man verstehen, ob es sich bei dieser „magischen Zahl“ tatsächlich um eine magische Zahl handelt oder ob es sich um einen „bekannten Aspekt der Domain“ handelt. Wenn es sich um eine Domain handelt, kann man sie nur dann mit einem Softcode versehen, wenn sie vorhanden ist wirklich gute Chance, dass es sich ändert.

  • Fehlercodes und Statusflags

    Diese sind niemals für Hardcode geeignet, wie jeder arme Bastard, der jemals mit der Previous action failed due to error code 46 getroffen wurde, Ihnen sagen kann. Wenn Ihre Sprache dies unterstützt, sollten Sie einen Aufzählungstyp verwenden. Andernfalls haben Sie normalerweise eine ganze Datei / ein ganzes Modul voller Konstanten, die die gültigen Werte für einen bestimmten Fehlertyp angeben.

    Lassen Sie mich niemals return 42 in einem Fehlerbehandler, capiche? Keine Ausreden.

Ich habe wahrscheinlich mehrere Szenarien ausgelassen, aber ich denke, das deckt die meisten davon ab zu hartem Code Zeug. Sei einfach nicht faul darüber; Es sollte eine bewusste Entscheidung sein und kein einfacher alter schlampiger Code.

Kommentare

  • Vielen Dank für die gute Aufschlüsselung! – Die meisten Leute ‚ denken nicht über alle Optionen nach, die ich hinzufügen würde. “ Umgebungskonfiguration “ – Ich denke, diese sollten vermieden werden (nicht fest codiert), da die meisten Daten in einer Konfigurationsdatei oder Datenbank gespeichert werden sollten. Dies folgt dem Prinzip von „, bei dem Daten und Logik getrennt bleiben. “ ist eine Hauptstütze von MVC oder MVVM. Zeichenfolge TestServerVar = “ foo „; Zeichenfolge ProdServerVal = “ bar „;

Antwort

Es gibt verschiedene Gründe, einer Nummer einen Bezeichner zuzuweisen.

  • Wenn sich die Nummer ändern könnte, Es sollte eine Kennung haben. Es ist viel einfacher, NUMBER_OF_PLANETS zu finden, als nach jeder Instanz von 9 zu suchen und zu prüfen, ob sie in 8 geändert werden sollte Zeichenfolgen müssen möglicherweise geändert werden, wenn die Software jemals in einer anderen Sprache verwendet werden muss, und dies ist „schwer vorherzusagen.)
  • If Die Zahl ist in keiner Weise schwer einzugeben. Für Konstanten wie pi ist es besser, eine Definition mit maximaler Genauigkeit anzugeben, als sie an mehreren Stellen erneut einzugeben, möglicherweise ungenau.
  • Wenn die Nummer an verschiedenen Stellen vorkommt. Sie sollten sich nicht zwei Verwendungen von 45 in benachbarten Funktionen ansehen und sich fragen müssen, ob sie dasselbe bedeuten.
  • Wenn die Bedeutung nicht sofort erkennbar ist. Es ist sicher anzunehmen, dass jeder weiß, was 3.14159265 … ist. Es ist nicht sicher, dies anzunehmen Jeder wird die Gravitationskonstante oder sogar pi / 2 erkennen. („Jeder“ hier hängt von der Art der Software ab. Von Systemprogrammierern kann erwartet werden, dass sie die oktale Darstellung von Unix-Berechtigungsbits oder dergleichen kennen. Überprüfen Sie in Software für Marine- / Schiffsarchitektur die Froude-Nummer eines vorgeschlagenen Rumpfs und die Geschwindigkeit auf Überprüfen Sie, ob es sich um 1.1 oder höher handelt, was für jeden, der daran arbeiten sollte, vollkommen selbsterklärend sein kann.)
  • Wenn der Kontext nicht erkennbar ist . Jeder weiß, dass eine Stunde 60 Minuten hat, aber das Multiplizieren oder Teilen mit 60 kann unklar sein, wenn es keine unmittelbaren Hinweise darauf gibt, dass die Menge ein Zeitwert oder ein Ratenwert ist

Dies gibt uns Kriterien für hartcodierte Literale. Sie sollten unveränderlich sein, nicht schwer zu tippen, nur an einem Ort oder in einem Kontext vorkommen und eine erkennbare Bedeutung haben. Es hat keinen Sinn zum Beispiel beim Definieren von 0 als ARRAY_BEGINNING oder 1 als ARRAY_INCREMENT.

Antwort

Als Ergänzung zu anderen Antworten. Verwenden Sie nach Möglichkeit Konstanten für Zeichenfolgen. Natürlich möchten Sie nicht

const string server_var="server_var"; 

haben, aber Sie sollten

const string MySelectQuery="select * from mytable;"; 

(vorausgesetzt, Sie haben tatsächlich immer eine Abfrage, bei der Sie alle Ergebnisse aus einer bestimmten Tabelle abrufen möchten)

Verwenden Sie ansonsten Konstanten für eine andere Zahl als 0 (normalerweise) Verwenden Sie für eine Berechtigungsbitmaske von 255 nicht

const int 8th_bit=255; //or some other obscure naming scheme that equates to 255. 

, sondern

const int AllowGlobalRead=255; 

Natürlich wissen Sie zusammen mit Konstanten, wann Enumeratoren verwendet werden müssen. Der obige Fall würde wahrscheinlich gut in einen passen.

Kommentare

  • typedef enum {state_0 = 0, state_1 = 1, state_2 = 2, .. .} … Nicht ‚ nicht lachen, ich ‚ habe es gesehen. Schlagen Sie diese Person mit einem nassen Fisch um den Kopf!
  • @schnell natürlich, Sie ‚ möchten etwas mehr wie typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
  • THIS_NAMING_CONVENTION_IS_RECOMMENDED_FOR_CONSTANTS
  • Für Zeichenfolgen möchten Sie ‚ nicht nur Konstanten. Sie möchten alle vom Benutzer sichtbaren Zeichenfolgen in eine Ressourcendatei einfügen (Details hängen von Ihrer Plattform ab), damit Sie problemlos in eine andere Sprache wechseln können.
  • Möglicherweise möchten Sie auch geschäftslogikbezogen bleiben Zeichenfolgen (wie SQL-Abfragen) in einer Ressourcendatei mit einer Art Verschlüsselung oder Verschleierung. Dadurch wird verhindert, dass “ neugierige “ Benutzer Ihre Logik (oder Ihr Datenbankschema) rückentwickeln.

Antwort

Es hängt davon ab, was Sie als Hardcodierung betrachten. Wenn Sie versuchen, alle fest codierten Dinge zu vermeiden, landen Sie im Gebiet softcoding und erstellen ein System, das nur der Ersteller verwalten kann (und das ist das ultimativer Hardcode)

Viele Dinge sind in einem vernünftigen Rahmen fest codiert und funktionieren. Das heißt, es gibt keinen technischen Grund, warum ich den Einstiegspunkt einer C # -Anwendung nicht ändern sollte (statische Leere Main) ), aber Hardcodierung, die für keinen Benutzer Probleme verursacht (mit Ausnahme der gelegentlichen SO-Frage )

Die Faustregel, die ich verwende, lautet dass alles, was sich ändern kann und wird, ohne den Zustand des gesamten Systems zu beeinflussen, konfugierbar sein sollte.

Also, IMHO, es ist dumm, Dinge, die sich nie ändern, nicht fest zu codieren (pi, Gravitationskonstante, eine Konstante in einer mathematischen Formel – denken Sie an das Volumen einer Kugel).

Es ist auch albern, Dinge oder Prozesse, die sich auf Ihr System auswirken und in jedem Fall programmiert werden müssen, nicht fest zu codieren, d.h. Es ist verschwenderisch, dem Benutzer das Hinzufügen dynamischer Felder zu einem Formular zu ermöglichen, wenn der Wartungsentwickler für ein hinzugefügtes Feld ein Skript schreiben müsste, mit dem das Ding funktioniert. Außerdem ist es dumm (und ich habe es einige Male in Unternehmensumgebungen gesehen), ein Konfigurationstool zu erstellen, sodass nichts fest codiert ist, aber nur die Entwickler in der IT-Abteilung können es verwenden, und es ist nur geringfügig einfacher Um es zu verwenden, als um es in Visual Studio zu tun.

Unterm Strich hängt es also von zwei Variablen ab, ob ein Objekt fest codiert werden soll:

  • ändert sich der Wert
  • Wie wirkt sich eine Änderung des Werts auf das System aus?

Antwort

Ist es jemals eine gute Idee, Werte in unsere Anwendungen fest zu codieren?

Ich habe Hardcode-Werte nur wenn die Werte sind in der Spezifikation angegeben (bei einer endgültigen Veröffentlichung der Spezifikation), z Die HTTP-OK-Antwort lautet immer 200 (es sei denn, sie ändert sich im RFC). Sie sehen also (in einigen meiner Codes) Konstanten wie:

public static final int HTTP_OK = 200; 

Andernfalls speichere ich Konstanten in der Eigenschaftendatei.

Der Grund, warum ich Spezifikationen angegeben habe, ist, dass das Ändern von Konstanten in Spezifikationen eine Änderungsverwaltung erfordert, in der die Die Stakeholder werden die Änderung überprüfen und genehmigen / ablehnen. Es passiert nie über Nacht und es dauert Monate / Jahre für eine Genehmigung. Vergessen Sie nicht, dass viele Entwickler Spezifikationen (z. B. HTTP) verwenden. Wenn Sie diese ändern, werden Millionen von Systemen beschädigt.

Antwort

    enn sich der Wert ändern kann und tatsächlich ändern kann, codieren Sie ihn nach Möglichkeit per Softcode, solange der Aufwand die erwartete Rendite nicht überschreitet.

  • Einige Werte können nicht sein Softcodiert; Befolgen Sie die Richtlinien von Jonathan in diesen (seltenen) Fällen.

Antwort

Ich habe es bemerkt Jedes Mal, wenn Sie Daten aus Ihrem Code extrahieren können, werden die verbleibenden Daten verbessert. Sie bemerken neue Refactorings und verbessern ganze Abschnitte Ihres Codes.

Es ist nur eine gute Idee, auf das Extrahieren von Konstanten hinzuarbeiten. Betrachten Sie es nicht als dumme Regel, sondern betrachten Sie es als Gelegenheit zum Codieren besser.

Der größte Vorteil wäre die Art und Weise, wie Sie ähnliche Konstanten als einzigen Unterschied in Codegruppen finden. Wenn ich sie in Arrays abstrahiere, kann ich einige Dateien um 90% ihrer Größe reduzieren und ganz korrigieren Einige kopieren & fügen in der Zwischenzeit Fehler ein.

Ich habe noch keinen einzigen Vorteil darin gesehen, keine Daten zu extrahieren.

Antwort

Ich habe kürzlich eine MySQL-Funktion codiert, um den Abstand zwischen zwei Lat / Long-Paaren richtig zu berechnen. Sie können nicht einfach Pythonagorus machen. Längengradlinien rücken näher zusammen, wenn der Breitengrad in Richtung der Pole zunimmt, so dass es sich um einen haarigen Trigger handelt. Der Punkt ist, ich war ziemlich hin und her gerissen, ob ich den Wert, der den Radius der Erde in Meilen darstellt, hart codieren soll.

Am Ende habe ich es getan, obwohl die Lat / Lng-Linien beispielsweise auf dem Mond viel näher beieinander liegen. Und meine Funktion würde Entfernungen zwischen Punkten auf Jupiter drastisch unterschätzen. Ich dachte, die Wahrscheinlichkeit, dass die Website, die ich baue, mit einem außerirdischen Standort betreten wird, ist ziemlich gering.

Kommentare

Antwort

Nun, es hängt davon ab, ob Ihre Sprache kompiliert ist. Wenn sie nicht kompiliert ist, ist es keine große Sache, Sie bearbeiten nur den Quellcode, auch wenn er für einen Nicht-Programmierer etwas heikel ist.

Wenn Sie mit einer kompilierten Sprache programmieren, ist dies eindeutig keine gute Idee. Wenn sich die Variablen ändern, müssen Sie sie neu kompilieren. Dies ist eine große Zeitverschwendung, wenn Sie diese Variable anpassen möchten.

Sie müssen keinen Schieberegler oder keine Schnittstelle erstellen, um seine Variable dynamisch zu ändern, aber das Mindeste, was Sie tun können, ist eine Textdatei.

Zum Beispiel verwende ich bei meinem Oger-Projekt immer Die ConfigFile-Klasse zum Laden einer Variablen, die ich in eine Konfigurationsdatei geschrieben habe.

Antwort

Zwei Fälle, in denen Konstanten (zumindest meiner Meinung nach) in Ordnung sind:

  1. Konstanten, die sich auf nichts anderes beziehen; Sie können diese Konstanten jederzeit ändern, ohne etwas anderes ändern zu müssen. Beispiel: Die Standardbreite einer Rasterspalte.

  2. Absolut unveränderliche, präzise, offensichtliche Konstanten wie „Anzahl der Tage pro Woche“. days = weeks * 7 Das Ersetzen von 7 durch eine Konstante DAYS_PER_WEEK liefert kaum einen Wert.

Antwort

Ich stimme Jonathan vollkommen zu, aber da es alle Regeln gibt, gibt es Ausnahmen …

„Magische Nummer in der Spezifikation: Magische Nummer im Code“

Gibt dies grundsätzlich an Alle magischen Zahlen, die nach vernünftigen Versuchen, einen beschreibenden Kontext für sie zu erhalten, in der Spezifikation verbleiben, sollten als solche im Code wiedergegeben werden. Wenn magische Zahlen im Code verbleiben, sollten alle Anstrengungen unternommen werden, um sie zu isolieren und eindeutig mit ihrem Ursprungsort zu verknüpfen.

Ich habe einige Schnittstellenverträge abgeschlossen, bei denen es erforderlich ist, Nachrichten mit zugeordneten Werten zu füllen aus der Datenbank. In den meisten Fällen ist die Zuordnung ziemlich einfach und würde in Jonathans allgemeine Richtlinien passen, aber ich bin auf Fälle gestoßen, in denen die Zielnachrichtenstruktur einfach schrecklich war.Mehr als 80% der Werte, die in der Struktur weitergegeben werden mussten, waren Konstanten, die durch die Spezifikation des entfernten Systems erzwungen wurden. Dies zusammen mit der Tatsache, dass die Nachrichtenstruktur gigantisch war, führte dazu, dass eine Menge solcher Konstanten gefüllt werden mussten. In den meisten Fällen gaben sie keine Bedeutung oder keinen Grund an, sondern sagten nur „M hier setzen“ oder „4.10.53.10100.889450.4452 hier setzen“. Ich habe auch nicht versucht, einen Kommentar neben alle zu setzen, da dies den resultierenden Code unlesbar gemacht hätte. Ich habe jedoch sichergestellt, dass die Codeabschnitte, in denen diese magischen Werte angezeigt werden, ordnungsgemäß isoliert sind und dass ihre Container (Klassen, Pakete) entsprechend benannt sind, um direkt auf die Spezifikation zu verweisen, die sie erzwingt.

Das heißt, wenn Sie darüber nachdenken es … es geht so ziemlich darum, es offensichtlich zu machen

Antwort

Wenn Sie den Wert der Gravitationskonstante der Erde „hart codieren“, wird es niemanden interessieren. Wenn Sie die IP-Adresse Ihres Proxyservers fest codieren, treten Probleme auf.

Kommentare

  • Möglicherweise benötigen Sie mehr Genauigkeit für earth ‚ s Gravitationskonstante, so dass eine mehrfache Hardcodierung zu Problemen führen kann.
  • Peter Noone? Von Hermans ‚ s Einsiedlern ?
  • Die Gravitationsbeschleunigung auf der Erde beträgt für die meisten Breiten und Höhen ziemlich 9,81 m / s ^ 2 (natürlich, wenn Sie ‚ nach Öl suchen Untergrund oder ICBMs über den Nordpol schießen, wobei die Kenntnis der Variation der Schwerkraft für viel mehr Dezimalstellen sehr wichtig ist), wobei die Gravitationsbeschleunigung auf anderen Planeten eine andere Zahl ist, aber meines Wissens ist die Gravitationskonstante konstant Es gibt eine Menge Physik, die sich ändern müsste, wenn g variabel wäre.

Antwort

Meistens nein, aber ich denke, das ist erwähnenswert, dass Sie wi Die meisten Probleme treten auf, wenn Sie mit dem Duplizieren des fest codierten Werts beginnen. Wenn Sie es nicht duplizieren (z. B. nur einmal bei der Implementierung einer Klasse verwenden), ist es möglicherweise in Ordnung, keine Konstante zu verwenden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.