Dies ist ein etwas kontroverses Thema, und ich denke, es gibt ebenso viele Meinungen wie Programmierer. Aber um es besser zu machen, möchte ich wissen, wie es in der Wirtschaft (oder an Ihren Arbeitsplätzen) üblich ist.
An meinem Arbeitsplatz haben wir strenge Kodierungsrichtlinien. Ein Abschnitt davon ist den magischen Zeichenfolgen / Zahlen gewidmet. Es heißt (für C #):
Verwenden Sie in Ihrem Code keine literalen Werte, weder numerische Werte noch Zeichenfolgen, außer um symbolische Konstanten zu definieren. Verwenden Sie das folgende Muster, um Konstanten zu definieren:
public class Whatever { public static readonly Color PapayaWhip = new Color(0xFFEFD5); public const int MaxNumberOfWheels = 18; }
Es gibt Ausnahmen: Die Werte 0, 1 und null können fast immer sicher verwendet werden. Sehr oft sind auch die Werte 2 und -1 in Ordnung. Zeichenfolgen, die für die Protokollierung oder Ablaufverfolgung vorgesehen sind, sind von dieser Regel ausgenommen. Literale sind zulässig, wenn ihre Bedeutung aus dem Kontext klar hervorgeht und künftigen Änderungen nicht mehr unterworfen ist.
mean = (a + b) / 2; // okay
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough
Eine ideale Situation wäre eine offizielle Studie, die Auswirkungen auf die Lesbarkeit / Wartbarkeit des Codes zeigt, wenn:
- Magische Zahlen / Strings sind überall
- Magische Zeichenfolgen / Zahlen werden vernünftigerweise (oder in unterschiedlichem Umfang) durch konstante Deklarationen ersetzt - und bitte schreien Sie mich nicht an, wenn Sie "vernünftigerweise" verwenden. Ich weiß, dass jeder eine andere Vorstellung davon hat, was "vernünftigerweise" ist
- Magische Zeichenfolgen / Zahlen werden im Übermaß und an Stellen, an denen sie nicht sein müssten, ersetzt (siehe mein Beispiel unten).
Ich möchte dies tun, um einige wissenschaftlich fundierte Argumente zu haben, wenn ich mit einem meiner Kollegen diskutiere, der Konstanten wie die folgenden deklariert:
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;
Ein anderes Beispiel wäre (und dieses ist in JavaScript):
var someNumericDisplay = new NumericDisplay("#Div_ID_Here");
Kleben Sie DOM-IDs auf Ihre Javascript-Datei, wenn diese ID nur an einer Stelle verwendet wird?
Ich habe die folgenden Themen gelesen:
StackExchange
StackOverflow
Bytes IT-Community
Es gibt viel mehr Artikel, und nach dem Lesen dieser Artikel tauchen einige Muster auf.
Meine Frage ist also, ob wir in unserem Code magische Zeichenfolgen und Zahlen verwenden sollen. Ich bin speziell auf der Suche nach kompetenten Antworten, die nach Möglichkeit durch Referenzen untermauert sind.
quelle
NumberTen = 10
Das ist sinnlos, da die Nummer 10 nicht neu definiert wird.MaxRetryCount = 10
Das hat einen Punkt, an dem wir die maximale Anzahl der Wiederholungen ändern möchten.private const char SemiColon = ';';
Dumm.private const char LineTerminator = ';'
; Clever.Antworten:
Das Argument, das Sie mit Ihrem Kollegen vorbringen müssen, besteht nicht darin, ein wörtliches Leerzeichen zu benennen,
Space
sondern in der schlechten Wahl des Namens für seine Konstanten.Angenommen, Ihr Code analysiert einen Datenstrom, der Felder enthält, die durch Semikolons (
a;b;c
) und durch Leerzeichen (a;b;c d;e;f
) voneinander getrennt sind . Wenn jemand, der Ihre Spezifikation geschrieben hat, Sie in einem Monat anruft und sagt: "Wir haben uns geirrt, die Felder in den Datensätzen sind durch Pipe-Symbole (a|b|c d|e|f
) getrennt." Was tun Sie?Unter dem Wert-as-Namensschema Ihres Kollege vorzieht, dann würden Sie den Wert der wörtlichen (ändern müssen
SemiColon = '|'
) und Live mit Code, der verwenden weiterhinSemiColon
für etwas , das nicht mehr wirklich ein Semikolon ist. Das führt zu negativen Kommentaren in Code Reviews . Um dies zu verringern, können Sie den Namen des Literales inPipeSymbol
ändern und jedes Vorkommen vonSemiColon
in durchgehen und ändernPipeSymbol
. In diesem Fall hätten Sie auch einfach ein Semikolon (';'
) verwenden können, da Sie jede Verwendung einzeln bewerten müssen und die gleiche Anzahl von Änderungen vornehmen müssen.Bezeichner für Konstanten müssen beschreiben, was der Wert tut , nicht was der Wert ist , und dort hat Ihr Kollege eine Linkskurve ins Unkraut gemacht. In der oben beschriebenen Feldaufteilungsanwendung dient das Semikolon als Feldtrennzeichen, und die Konstanten sollten entsprechend benannt werden:
Auf diese Weise ändern Sie beim Ändern des Feldtrennzeichens genau eine Codezeile, die Deklaration der Konstante. Jemand, der sich die Änderung ansieht, sieht nur diese eine Zeile und erkennt sofort, dass sich das Feldtrennzeichen von einem Semikolon in ein Pipe-Symbol geändert hat. Der Rest des Codes, der sich nicht ändern musste, weil er eine Konstante verwendete, bleibt derselbe, und der Leser muss nicht darin stöbern, um zu sehen, was noch getan wurde.
quelle
#define one 1 #define two 2
etc deklariert (oder was auch immer das Äquivalent war in UK Post Office Coral, der Sprache der Wahl). Es kam die#define one 8 #define two 16
;
in|
.public static final String MY_KEY_NAME = "MyKeyName"
CSV_RECORD_SEPARATOR
,TSV_RECORD_SEPARATOR
usw.).Die Definition von Semikolon als Konstante ist überflüssig, da Semikolon für sich genommen bereits konstant ist . Es wird sich nie ändern.
Es ist nicht so, dass irgendjemand eines Tages "Änderung der Terminologie, + ist jetzt das neue Semikolon" ankündigt , und Ihr Kollege wird sich gerne beeilen, nur um die Konstante zu aktualisieren (sie haben mich ausgelacht - schauen Sie sie sich jetzt an).
Es gibt auch eine Frage der Konsistenz. Ich garantiere, dass seine
NumberTen
Konstante NICHT von jedem verwendet wird (die meisten Programmierer sind nicht verrückt), so dass sie nicht dem Zweck dient, den sie ohnehin erwartet hatten. Wenn die Apokalypse kommt und "zehn" global auf 9 skaliert wird, reicht die Aktualisierung der Konstante NICHT aus, da Sie immer noch eine Menge wörtlicher10
s in Ihrem Code haben, sodass das System selbst innerhalb des Gültigkeitsbereichs völlig unvorhersehbar wird einer revolutionären Annahme, dass "zehn" "9" bedeutet.Das Speichern aller Einstellungen als consts ist etwas, worüber ich mir auch Gedanken machen muss. Man sollte das nicht leichtfertig machen.
Welche Beispiele für diese Art der Nutzung haben wir bisher gesammelt? Zeilenabschluss ... Maximale Anzahl der Wiederholungsversuche ... Maximale Anzahl der Räder ... Sind wir sicher, dass sich diese niemals ändern werden?
Das Ändern der Standardeinstellungen erfordert eine Neukompilierung einer Anwendung und in einigen Fällen sogar ihrer Abhängigkeiten (da numerische Konstantenwerte während der Kompilierung möglicherweise fest codiert werden).
Es gibt auch den Test- und Spottaspekt. Sie haben die Verbindungszeichenfolge als const definiert, aber jetzt können Sie den Datenbankzugriff (Herstellen einer falschen Verbindung) in Ihrem Komponententest nicht verspotten.
quelle
’
(linkes einfaches Anführungszeichen, Unicode 8217 ) für Apps verwendet, die mit einer anderen Glyphe für die gewellte Marke kompatibel sind. Da Europa Kommas verwendet, wie die Amerikaner Punkte als Dezimaltrennzeichen verwenden, zögere ich ein bisschen, "nicht ... jemals" zu deklarieren.DecimalPoint
Konstante - aber nichtComma
oderPeriod
Konstanten. Es ist ein ziemlicher Unterschied: Ersteres bezeichnet eine Funktion , eine Rolle oder einen Zweck des Wertes. "Semikolon" oder "Komma" fallen nicht unter diese Kategorie.Ihr Kollege strebt also einen täglichen WTF-Eintrag an. Diese Definitionen sind albern und überflüssig. Wie jedoch von anderen betont wurde, wären die folgenden Definitionen nicht dumm oder überflüssig:
"Magische" Zahlen und Zeichenfolgen sind Konstanten, deren Bedeutung über ihren unmittelbaren, wörtlichen Wert hinausgeht. Wenn die Konstante
10
eine Bedeutung hat, die über "zehn Dinge" hinausgeht (beispielsweise als Code für eine bestimmte Operation oder einen bestimmten Fehlerzustand), wird sie zu "Magie" und sollte durch eine symbolische Konstante ersetzt werden, die diese abstrakte Bedeutung beschreibt.Symbolische Konstanten beschreiben nicht nur die Absicht, sondern ersparen Ihnen auch Kopfschmerzen, wenn Sie ein Literal falsch schreiben. Eine einfache Umstellung von "CVS" auf "CSV" in einer Codezeile durchlief den gesamten Unit-Test und die Qualitätssicherung und schaffte es in die Produktion, wo ein bestimmter Vorgang fehlschlug. Ja, offensichtlich waren die Geräte- und QS-Tests unvollständig und das ist ein eigenes Problem, aber die Verwendung einer symbolischen Konstante hätte dieses bisschen Sodbrennen insgesamt vermieden.
quelle
Daran sollte nichts Kontroverses sein. Es geht nicht darum, ob magische Zahlen verwendet werden sollen oder nicht, es geht darum, lesbaren Code zu haben.
Betrachten Sie den Unterschied zwischen:
if(request.StatusCode == 1)
undif(request.HasSucceeded)
. In diesem Fall würde ich behaupten, dass Letzteres weitaus besser lesbar ist, aber das bedeutet nicht, dass Sie niemals Code wie diesen haben könnenint MaxNumberOfWheels = 18
.PS: Deshalb hasse ich Kodierungsrichtlinien. Entwickler sollten ausgereift genug sein, um solche Urteilsforderungen zu stellen. Sie sollten es nicht einem Textstück überlassen, das von Gott weiß, wer gebildet wurde.
quelle