Uns allen ist bewusst, dass magische Zahlen (fest codierte Werte) in Ihrem Programm Chaos anrichten können, insbesondere wenn es an der Zeit ist, einen Codeabschnitt ohne Kommentare zu ändern, aber wo ziehen Sie die Linie?
Wenn Sie beispielsweise eine Funktion haben, die die Anzahl der Sekunden zwischen zwei Tagen berechnet, ersetzen Sie diese
seconds = num_days * 24 * 60 * 60
mit
seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
Ab wann entscheiden Sie, dass es völlig offensichtlich ist, was der fest codierte Wert bedeutet, und lassen Sie es in Ruhe?
refactoring
coding-standards
maintainability
Oosterwal
quelle
quelle
seconds = CALC_SECONDS(num_days);
TimeSpan.FromDays(numDays).Seconds;
HOURS_PER_DAY will never need to be altered
) werden Sie niemals für Software programmieren, die auf dem Mars bereitgestellt wird. : PAntworten:
Es gibt zwei Gründe, symbolische Konstanten anstelle von numerischen Literalen zu verwenden:
Vereinfachung der Wartung, wenn sich die magischen Zahlen ändern. Dies gilt nicht für Ihr Beispiel. Es ist äußerst unwahrscheinlich, dass sich die Anzahl der Sekunden pro Stunde oder die Anzahl der Stunden pro Tag ändert.
Zur Verbesserung der Lesbarkeit. Der Ausdruck "24 * 60 * 60" ist für fast jeden offensichtlich. "SECONDS_PER_DAY" ist auch, aber wenn Sie einen Fehler suchen, müssen Sie möglicherweise überprüfen, ob SECONDS_PER_DAY richtig definiert wurde. In der Kürze liegt der Wert.
Bei magischen Zahlen, die genau einmal vorkommen und vom Rest des Programms unabhängig sind, ist es Geschmackssache, ein Symbol für diese Zahl zu erstellen. Im Zweifelsfall erstellen Sie ein Symbol.
Mach das nicht:
quelle
publid final int FOUR = 3;
public static int THREE = 3;
... Hinweis - neinfinal
!Ich würde die Regel einhalten, niemals magische Zahlen zu haben.
Während
Ist die meiste Zeit perfekt lesbar, nachdem Sie drei oder vier Wochen lang 10 Stunden am Tag im Crunch-Modus codiert haben
ist viel einfacher zu lesen.
Der Vorschlag von FrustratedWithFormsDesigner ist besser:
oder noch besser
Dinge hören auf, offensichtlich zu sein, wenn Sie sehr müde sind. Defensiv codieren .
quelle
Die Zeit, nein zu sagen, ist fast immer. In Zeiten, in denen es für mich einfacher ist, nur fest codierte Zahlen zu verwenden, ist dies beispielsweise beim Layout der Benutzeroberfläche der Fall. Die Erstellung einer Konstanten für die Positionierung jedes Steuerelements im Formular ist sehr umfangreich und anstrengend macht nicht viel aus. ... es sei denn, die Benutzeroberfläche ist dynamisch angeordnet oder verwendet relative Positionen zu einem Anker oder wird von Hand geschrieben. In diesem Fall ist es besser, einige sinnvolle Konstanten für das Layout zu definieren. Und wenn Sie hier oder dort einen Fudge-Faktor benötigen, um etwas "Genau Richtiges" auszurichten / zu positionieren, sollte dies ebenfalls definiert werden.
Aber in Ihrem Beispiel denke ich, dass das Ersetzen
24 * 60 * 60
durchDAYS_TO_SECONDS_FACTOR
besser ist.Ich gebe zu, dass hartcodierte Werte auch dann in Ordnung sind, wenn der Kontext und die Verwendung vollständig klar sind. Dies ist jedoch ein Urteilsspruch ...
Beispiel:
Wie @rmx hervorhob, ist die Verwendung von 0 oder 1, um zu überprüfen, ob eine Liste leer ist, oder möglicherweise in den Grenzen einer Schleife, ein Beispiel für einen Fall, in dem der Zweck der Konstante sehr klar ist.
quelle
0
oder1
ich rechne damit.if(someList.Count != 0) ...
ist besser alsif(someList.Count != MinListCount) ...
. Nicht immer, aber allgemein.Stoppen Sie, wenn Sie der Zahl keine Bedeutung oder keinen Zweck zuordnen können.
ist viel einfacher zu lesen als nur die Zahlen zu verwenden. (Es könnte zwar durch eine einzelne
SECONDS_PER_DAY
Konstante besser lesbar gemacht werden , aber es ist ein völlig separates Problem.)Angenommen, ein Entwickler, der sich den Code ansieht, kann sehen, was er tut. Aber nehmen Sie nicht an, dass sie auch wissen warum. Wenn Ihre Konstante hilft, das Warum zu verstehen, versuchen Sie es. Wenn nicht, dann nicht.
Wenn Sie am Ende zu viele Konstanten haben, wie in einer Antwort vorgeschlagen, sollten Sie stattdessen eine externe Konfigurationsdatei verwenden, da Dutzende von Konstanten in einer Datei die Lesbarkeit nicht gerade verbessern.
quelle
Ich würde wahrscheinlich zu Dingen wie "Nein" sagen:
Und würde definitiv "nein" sagen zu:
quelle
Eines der besten Beispiele, die ich gefunden habe, um die Verwendung von Konstanten für offensichtliche Dinge zu fördern,
HOURS_PER_DAY
ist:Wir haben berechnet, wie lange sich die Dinge in der Job-Warteschlange einer Person befanden. Die Anforderungen wurden lose definiert und der Programmierer
24
an mehreren Stellen fest programmiert . Schließlich stellten wir fest, dass es nicht fair war, die Benutzer dafür zu bestrafen, dass sie 24 Stunden lang auf einem Problem saßen, obwohl sie eigentlich nur 8 Stunden am Tag arbeiteten. Als die Aufgabe kam, dieses Problem zu beheben UND herauszufinden, welche anderen Berichte das gleiche Problem haben könnten, war es ziemlich schwierig, den Code nach 24 zu durchsuchen. Es wäre viel einfacher gewesen, nach diesen zu suchenHOURS_PER_DAY
quelle
Ich denke, solange die Zahl völlig konstant ist und sich nicht ändern kann, ist sie vollkommen akzeptabel. Also in Ihrem Fall
seconds = num_days * 24 * 60 * 60
ist es in Ordnung (vorausgesetzt natürlich, dass Sie nichts Dummes tun, wie diese Art der Berechnung in einer Schleife) und für die Lesbarkeit wahrscheinlich besser alsseconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
.Es ist schlecht, wenn man so etwas macht:
lineOffset += 24; // 24 lines to a page
Verwenden Sie stattdessen eine konstante Variable, auch wenn Sie keine Zeilen mehr in die Seite einfügen konnten oder nicht beabsichtigen, sie zu ändern, da sie eines Tages zurückkehren wird, um Sie zu verfolgen. Letztendlich geht es um Lesbarkeit und nicht um die Einsparung von 2 Berechnungszyklen auf der CPU. Dies ist nicht mehr 1978, als kostbare Bytes für alle ihren Wert gequetscht wurden.
quelle
Ist vollkommen in Ordnung. Dies sind keine magischen Zahlen, da sie sich nie ändern werden.
Alle Zahlen, die sich vernünftigerweise ändern können oder keine offensichtliche Bedeutung haben, sollten in Variablen eingegeben werden. Das bedeutet so ziemlich alles.
quelle
seconds = num_days * 86400
noch akzeptabel? Wenn ein solcher Wert mehrmals in vielen verschiedenen Dateien verwendet würde, wie würden Sie überprüfen, ob jemand nicht versehentlichseconds = num_days * 84600
an einer oder zwei Stellen getippt hat ?Ich würde vermeiden, Konstanten (magische Werte) zu erstellen, um einen Wert von einer Einheit in eine andere umzuwandeln. Bei der Konvertierung bevorzuge ich einen sprechenden Methodennamen. In diesem Beispiel wäre dies zB
DayToSeconds(num_days)
intern. Die Methode benötigt keine magischen Werte, da die Bedeutung von "24" und "60" klar ist.In diesem Fall würde ich niemals Sekunden / Minuten / Stunden verwenden. Ich würde nur TimeSpan / DateTime verwenden.
quelle
Verwenden Sie den Kontext als Parameter, um zu entscheiden
Wenn Sie beispielsweise eine Funktion mit dem Namen "berechne Sekunden zwischen: einem Tag und: einem anderen Tag" haben, brauchen Sie nicht viel zu erklären, was diese Zahlen tun, da der Funktionsname ziemlich repräsentativ ist.
Und eine andere Frage ist, welche Möglichkeiten gibt es, es anders zu berechnen? Manchmal gibt es viele Möglichkeiten, das Gleiche zu tun, um zukünftige Programmierer anzuleiten und ihnen zu zeigen, welche Methode Sie verwendet haben. Die Definition von Konstanten könnte dabei helfen, dies herauszufinden.
quelle