Nous sommes tous conscients que les nombres magiques (valeurs codées en dur) peuvent causer des ravages dans votre programme, en particulier lorsqu'il est temps de modifier une section de code sans commentaires, mais où tracez-vous la ligne?
Par exemple, si vous avez une fonction qui calcule le nombre de secondes entre deux jours, remplacez-vous
seconds = num_days * 24 * 60 * 60
avec
seconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
À quel moment décidez-vous qu'il est tout à fait évident de comprendre la valeur codée en dur et laissez-la tranquille?
refactoring
coding-standards
maintainability
Oosterwal
la source
la source
seconds = CALC_SECONDS(num_days);
TimeSpan.FromDays(numDays).Seconds;
HOURS_PER_DAY will never need to be altered
), vous ne coderez jamais pour les logiciels déployés sur Mars. : PRéponses:
Il y a deux raisons d'utiliser des constantes symboliques au lieu de littéraux numériques:
Pour simplifier la maintenance si les nombres magiques changent. Cela ne s'applique pas à votre exemple. Il est extrêmement improbable que le nombre de secondes dans une heure ou le nombre d'heures dans une journée change.
Pour améliorer la lisibilité. L'expression "24 * 60 * 60" est assez évidente pour presque tout le monde. "SECONDS_PER_DAY" l'est également, mais si vous recherchez un bogue, vous devrez peut-être vérifier que SECONDS_PER_DAY a été défini correctement. Il y a de la valeur dans la brièveté.
Pour les nombres magiques qui apparaissent exactement une fois et qui sont indépendants du reste du programme, décider de créer un symbole pour ce nombre est une question de goût. En cas de doute, créez un symbole.
Ne faites pas cela:
la source
publid final int FOUR = 3;
public static int THREE = 3;
... note - nonfinal
!Je garderais la règle de ne jamais avoir de nombres magiques.
Tandis que
Est parfaitement lisible la plupart du temps, après avoir codé 10 heures par jour pendant trois ou quatre semaines en mode crunch
est beaucoup plus facile à lire.
La suggestion de FrustratedWithFormsDesigner est meilleure:
ou même mieux
Les choses cessent d'être évidentes lorsque vous êtes très fatigué. Code défensivement .
la source
Le temps de dire non est presque toujours. Il est parfois plus facile d'utiliser des nombres codés en dur, par exemple, dans la disposition de l'interface utilisateur: créer une constante pour le positionnement de chaque contrôle sur la fiche devient très fastidieux et fatigant, et si ce code est généralement géré par un concepteur d'interface utilisateur, il Peu importe. ... sauf si l'interface utilisateur est agencée de manière dynamique, ou utilise des positions relatives par rapport à une ancre ou est écrite à la main. Dans ce cas, je dirais qu'il est préférable de définir des constantes significatives pour la mise en page. Et si vous avez besoin d’un facteur de fudge ici ou là pour aligner / positionner quelque chose de "juste", vous devez également le définir.
Mais dans votre exemple, je pense que remplacer
24 * 60 * 60
par,DAYS_TO_SECONDS_FACTOR
c'est mieux.J'admets que les valeurs codées en dur conviennent également lorsque le contexte et l'utilisation sont parfaitement clairs. Ceci, cependant, est un appel de jugement ...
Exemple:
Comme @rmx l'a fait remarquer, utiliser 0 ou 1 pour vérifier si une liste est vide ou peut-être dans les limites d'une boucle est un exemple de cas où l'objectif de la constante est très clair.
la source
0
ou1
je pense.if(someList.Count != 0) ...
est meilleur queif(someList.Count != MinListCount) ...
. Pas toujours, mais en général.Arrêtez-vous lorsque vous ne parvenez pas à donner un sens ou un but au nombre.
est beaucoup plus facile à lire que juste en utilisant les chiffres. (Bien que cela puisse être rendu plus lisible avec une seule
SECONDS_PER_DAY
constante, mais c'est une question complètement distincte.)Supposons qu'un développeur qui examine le code puisse voir ce qu'il fait. Mais ne supposez pas qu’ils savent aussi pourquoi. Si votre constante vous aide à comprendre le pourquoi, allez-y. Si non, ne le faites pas.
Si vous vous retrouvez avec trop de constantes, comme suggéré par une réponse, envisagez plutôt d'utiliser un fichier de configuration externe, car avoir des dizaines de constantes dans un fichier n'améliore pas vraiment la lisibilité.
la source
Je dirais probablement "non" à des choses comme:
Et sans aucun doute serait dire « non » à:
la source
L'un des meilleurs exemples que j'ai trouvé pour promouvoir l'utilisation de constantes pour des raisons évidentes
HOURS_PER_DAY
est le suivant:Nous étions en train de calculer combien de temps les choses restaient dans la file d'attente d'une personne. Les exigences ont été définies de manière vague et le programmeur a été codé
24
en dur à plusieurs endroits. Finalement, nous avons réalisé qu'il n'était pas juste de punir les utilisateurs pour s'être assis sur un problème pendant 24 heures alors que cela ne fonctionnait réellement que 8 heures par jour. Quand la tâche est venue de résoudre ce problème ET de voir quels autres rapports pourraient avoir le même problème, il était assez difficile de passer par grep / rechercher dans le code 24 aurait été beaucoup plus facile à rechercherHOURS_PER_DAY
la source
Je pense que tant que le nombre est complètement constant et n’a aucune possibilité de changer, il est parfaitement acceptable. Donc, dans votre cas, tout
seconds = num_days * 24 * 60 * 60
va bien (en supposant bien sûr que vous ne faites pas quelque chose de stupide comme faire ce genre de calcul dans une boucle) et sans doute mieux pour la lisibilité queseconds = num_days * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE
.C'est quand tu fais des choses comme ça que c'est mauvais:
lineOffset += 24; // 24 lines to a page
Même si vous ne pouvez plus insérer de lignes sur la page ou si vous n'avez pas l'intention de la modifier, utilisez plutôt une variable constante, car un jour, elle reviendra vous hanter. En fin de compte, le point essentiel est la lisibilité et non l’économie de 2 cycles de calcul sur le CPU. Ce n'est plus en 1978, lorsque de précieux octets ont été compressés pour toute leur valeur.
la source
Est parfaitement bien. Ce ne sont pas vraiment des nombres magiques car ils ne changeront jamais.
Tous les nombres qui peuvent raisonnablement changer ou qui n’ont pas de signification évidente doivent être intégrés aux variables. Ce qui signifie à peu près tous.
la source
seconds = num_days * 86400
toujours acceptable? Si une telle valeur était utilisée plusieurs fois dans de nombreux fichiers, comment pourriez-vous vérifier que quelqu'un n'a pas saisi accidentellementseconds = num_days * 84600
à un ou deux endroits?J'éviterais de créer des constantes (valeurs magiques) pour convertir une valeur d'une unité à une autre. En cas de conversion, je préfère un nom de méthode parlante. Dans cet exemple, cela serait par exemple
DayToSeconds(num_days)
interne, la méthode n'a pas besoin de valeurs magiques car la signification de "24" et "60" est claire.Dans ce cas, je n’utiliserais jamais secondes / minutes / heures. Je voudrais seulement utiliser TimeSpan / DateTime.
la source
Utiliser le contexte comme paramètre pour décider
Par exemple, vous avez une fonction appelée "CalculateSecondsBetween: aDay et: anotherDay", vous n'avez pas besoin de beaucoup expliquer ce que font ces nombres, car le nom de la fonction est assez représentatif.
Et une autre question est, quelles sont les possibilités de le calculer différemment? Parfois, il y a beaucoup de façons de faire la même chose, alors pour guider les futurs programmeurs et leur montrer quelle méthode vous avez utilisée, la définition de constantes pourrait aider à le comprendre.
la source