Qu'est-ce qu'un nombre magique et pourquoi est-il mauvais? [fermé]


514

Qu'est-ce qu'un nombre magique?

Pourquoi faut-il l'éviter?

Y a-t-il des cas où cela est approprié?


2
Vous éviteriez les nombres magiques car les autres personnes qui consultent votre code pourraient ne pas comprendre pourquoi vous faites ce que vous faites ... Par exemple, en const myNum = 22; const number = myNum / 11;ce moment, mes 11 pourraient être des gens ou des bouteilles de bière ou quelque chose comme ça, je changerais donc 11 en constante comme les habitants.
JuicY_Burrito

L'utilisation de nombres magiques dans les attributs est inévitable, donc je suppose que c'est approprié.
donatasj87

Réponses:


575

Un nombre magique est une utilisation directe d'un nombre dans le code.

Par exemple, si vous avez (en Java):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

Cela devrait être refactorisé pour:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

Il améliore la lisibilité du code et est plus facile à maintenir. Imaginez le cas où j'ai défini la taille du champ de mot de passe dans l'interface graphique. Si j'utilise un nombre magique, chaque fois que la taille maximale change, je dois changer dans deux emplacements de code. Si j'en oublie un, cela conduira à des incohérences.

Le JDK est plein d'exemples comme dans Integer, Characteret les Mathclasses.

PS: Des outils d'analyse statique comme FindBugs et PMD détectent l'utilisation de nombres magiques dans votre code et suggèrent le refactoring.


175
0 et 1 sont des exceptions à cette règle.
Jonathan Parker

24
@Kirill: Si vous vous attendez à ce que la définition de "Cent pour cent" change, alors oui. Une meilleure approche serait d'avoir la variable de ce qu'elle est à ce qu'elle représente, c.-à-d., Public statique final MAX_DOWNLOAD_PERCENTAGE = 100. Même si cela n'a pas de sens, car "100 pour cent" est très bien défini. D'un autre côté, le fait que les mots de passe peuvent avoir un maximum de 7 caractères n'est pas défini de manière globale et diffère en fait, c'est donc un candidat pour une variable.
Michael Stum

40
@Jonathan Parker, sauf quand ils ne le sont pas ( TRUE/ FALSE)
Brendan Long

82
Ce n'est pas parce qu'un nombre magique ne changera jamais qu'il ne doit pas être remplacé par une constante. Mon code est plein de constantes globales comme HzPerMHz et msecPerSecond. Celles-ci ne changeront jamais, mais elles rendent le sens plus clair et offrent une certaine protection contre les fautes de frappe.
Jeanne Pindar

43
@MarcusJ Vous ne pourriez pas vous tromper davantage. Ce n'est pas une question d'opinion, mais une expérience durement gagnée par de nombreux programmeurs. Je ne peux pas vous dire combien de fois, au cours des 40 dernières années de programmation, j'ai maudit un programmeur précédent qui n'a pas défini de constante, donc je n'ai découvert que l'utilisation directe d'un nombre, qui devait être compris pendant la maintenance du code , enterré quelque part dans beaucoup de code, dont le sens aurait été précisé en définissant une telle constante. Tout autre programmeur senior aura également plusieurs histoires d'horreur le long de cette ligne.
ToolmakerSteve

146

Un nombre magique est une valeur codée en dur qui peut changer à un stade ultérieur, mais qui peut donc être difficile à mettre à jour.

Par exemple, supposons que vous ayez une page qui affiche les 50 dernières commandes dans une page de présentation «Vos commandes». 50 est le nombre magique ici, car il n'est pas défini par une norme ou une convention, c'est un nombre que vous avez composé pour les raisons décrites dans la spécification.

Maintenant, ce que vous faites, c'est que vous avez les 50 à différents endroits - votre script SQL ( SELECT TOP 50 * FROM orders), votre site Web (vos 50 dernières commandes), votre identifiant de commande ( for (i = 0; i < 50; i++)) et éventuellement de nombreux autres endroits.

Maintenant, que se passe-t-il lorsque quelqu'un décide de passer de 50 à 25? ou 75? ou 153? Vous devez maintenant remplacer le 50 dans tous les endroits, et vous risquez de le manquer. Rechercher / Remplacer peut ne pas fonctionner, car 50 peut être utilisé pour d'autres choses, et le remplacement aveugle de 50 par 25 peut avoir d'autres effets secondaires néfastes (par exemple, votre Session.Timeout = 50appel, qui est également défini sur 25 et les utilisateurs commencent à signaler des délais d'attente trop fréquents).

En outre, le code peut être difficile à comprendre, c'est-à-dire " if a < 50 then bla" - si vous rencontrez cela au milieu d'une fonction compliquée, d'autres développeurs qui ne connaissent pas le code peuvent se demander "WTF is 50 ???"

C'est pourquoi il est préférable d'avoir de tels nombres ambigus et arbitraires à exactement 1 endroit - " const int NumOrdersToDisplay = 50", car cela rend le code plus lisible (" if a < NumOrdersToDisplay", cela signifie également que vous n'avez besoin de le changer qu'à 1 endroit bien défini.

Les endroits où les nombres magiques sont appropriés sont tout ce qui est défini par une norme, c'est-à-dire SmtpClient.DefaultPort = 25ou TCPPacketSize = whatever(je ne sais pas si cela est normalisé). De plus, tout ce qui n'est défini que dans 1 fonction peut être acceptable, mais cela dépend du contexte.


18
Même si cela ne peut pas changer, c'est toujours une mauvaise idée car ce n'est pas clair.
Loren Pechtel

11
Ce n'est pas toujours flou. SmtpClient.DefaultPort = 25est peut - être clair er que SmtpClient.DefaultPort = DEFAULT_SMTP_PORT.
user253751

4
@immibis Je suppose que cela suppose qu'il n'y a absolument aucun autre code qui utilise le concept de DEFAULT_SMTP_PORT. Si le port SMTP par défaut de cette application est modifié, il devra être mis à jour à plusieurs endroits, ce qui entraînera la possibilité d'une incohérence.
Russ Bradberry

3
Il est également plus difficile de trouver toutes les utilisations - vous devez rechercher dans 25toute l'application et vous assurer que vous ne modifiez que les occurrences du 25port SMTP, pas les 25 qui sont par exemple la largeur d'une colonne de tableau ou le nombre d'enregistrements à afficher sur une page.
Michael Stum

2
Dans cet exemple, je m'attendrais à ce que le code utilise SmtpClient.DefaultPort, et non 25. Il vous suffirait donc de le modifier au même endroit. Et le numéro de port est susceptible de rester le même, ce n'est pas un nombre magique aléatoire, mais un numéro attribué par IANA.
njsg

34

Avez-vous jeté un œil à l'entrée Wikipedia pour le nombre magique?

Il va dans un peu de détails sur toutes les façons dont la référence magique est faite. Voici une citation sur le nombre magique comme une mauvaise pratique de programmation

Le terme nombre magique fait également référence à la mauvaise pratique de programmation consistant à utiliser des nombres directement dans le code source sans explication. Dans la plupart des cas, cela rend les programmes plus difficiles à lire, à comprendre et à maintenir. Bien que la plupart des guides fassent une exception pour les nombres zéro et un, c'est une bonne idée de définir tous les autres nombres dans le code en tant que constantes nommées.


8
Bon exemple de RTFW :)
Eva

Je dirais que la réponse est loin d'être complète.
Skeeve

25

Nombre magique contre. Constante symbolique: quand remplacer?

Magie: sémantique inconnue

Constante symbolique -> Fournit à la fois un contexte sémantique et un contexte corrects à utiliser

Sémantique: le sens ou le but d'une chose.

"Créez une constante, nommez-la d'après la signification et remplacez-la par le nombre." - Martin Fowler

Premièrement, les nombres magiques ne sont pas seulement des nombres. Toute valeur de base peut être "magique". Les valeurs de base sont des entités manifestes telles que des entiers, des réels, des doubles, des flottants, des dates, des chaînes, des booléens, des caractères, etc. Le problème n'est pas le type de données, mais l'aspect "magique" de la valeur telle qu'elle apparaît dans notre texte de code.

Qu'entendons-nous par «magie»? Pour être précis: Par «magie», nous entendons pointer la sémantique (sens ou finalité) de la valeur dans le contexte de notre code; qu'il est inconnu, inconnaissable, peu clair ou déroutant. C'est la notion de "magie". Une valeur de base n'est pas magique lorsque sa signification sémantique ou son but d'être-là est rapidement et facilement connu, clair et compris (ne prêtant pas à confusion) à partir du contexte environnant sans mots auxiliaires spéciaux (par exemple, constante symbolique).

Par conséquent, nous identifions les nombres magiques en mesurant la capacité d'un lecteur de code à connaître, à être clair et à comprendre la signification et le but d'une valeur de base à partir de son contexte environnant. Moins le lecteur est connu, moins clair et confus, plus la valeur de base est "magique".

Définitions utiles

  • confondre: rendre (quelqu'un) perplexe ou perplexe.
  • perplexe: amener (quelqu'un) à devenir perplexe et confus.
  • perplexe: complètement déconcerté; très perplexe.
  • dérouté: totalement dérouté ou perplexe.
  • perplexe: incapable de comprendre; perplexe.
  • comprendre: percevoir la signification voulue de (mots, langue ou locuteur).
  • sens: ce que l'on entend par un mot, un texte, un concept ou une action.
  • signifiait: avoir l'intention de transmettre, d'indiquer ou de faire référence à (une chose ou une notion particulière); signifier.
  • signifier: être une indication de.
  • indication: un signe ou une information qui indique quelque chose.
  • indiquer: signaler; spectacle.
  • signe: un objet, une qualité ou un événement dont la présence ou l'occurrence indique la présence ou l'occurrence probable d'autre chose.

Les bases

Nous avons deux scénarios pour nos valeurs de base magiques. Seul le second est de première importance pour les programmeurs et le code:

  1. Une valeur de base isolée (par exemple, un nombre) dont la signification est inconnue, inconnaissable, peu claire ou déroutante.
  2. Une valeur de base (par exemple, un nombre) dans le contexte, mais sa signification reste inconnue, inconnaissable, peu claire ou déroutante.

Une dépendance globale de la «magie» est la façon dont la valeur de base isolée (par exemple, le nombre) n'a pas de sémantique connue (comme Pi), mais a une sémantique connue localement (par exemple, votre programme), qui n'est pas entièrement claire du contexte ou pourrait être abusée dans un bon ou un mauvais contexte.

La sémantique de la plupart des langages de programmation ne nous permettra pas d'utiliser des valeurs de base isolées, sauf (peut-être) comme données (c'est-à-dire des tableaux de données). Lorsque nous rencontrons des «nombres magiques», nous le faisons généralement dans un contexte. Par conséquent, la réponse à

"Dois-je remplacer ce nombre magique par une constante symbolique?"

est:

"En combien de temps pouvez-vous évaluer et comprendre la signification sémantique du nombre (sa raison d'être là) dans son contexte?"

Genre de magie, mais pas tout à fait

Avec cette pensée à l'esprit, nous pouvons rapidement voir comment un nombre comme Pi (3.14159) n'est pas un "nombre magique" lorsqu'il est placé dans le contexte approprié (par exemple 2 x 3.14159 x rayon ou 2 * Pi * r). Ici, le nombre 3,14159 est mentalement reconnu Pi sans l'identifiant de constante symbolique.

Pourtant, nous remplaçons généralement 3.14159 par un identificateur de constante symbolique comme Pi en raison de la longueur et de la complexité du nombre. Les aspects de longueur et de complexité de Pi (couplés à un besoin de précision) signifient généralement que l'identifiant symbolique ou la constante est moins sujet aux erreurs. La reconnaissance de "Pi" comme nom est simplement un bonus pratique, mais ce n'est pas la principale raison d'avoir la constante.

Pendant ce temps, au ranch

En mettant de côté les constantes communes comme Pi, concentrons-nous principalement sur les nombres ayant des significations spéciales, mais dont ces significations sont limitées à l'univers de notre système logiciel. Un tel nombre peut être "2" (comme valeur entière de base).

Si j'utilise le chiffre 2 seul, ma première question pourrait être: que signifie «2»? Le sens de "2" en lui-même est inconnu et inconnaissable sans contexte, laissant son utilisation peu claire et déroutante. Même si le fait de n'avoir que "2" dans notre logiciel ne se produira pas à cause de la sémantique du langage, nous voulons voir que "2" en lui-même n'a aucune sémantique particulière ou objectif évident étant seul.

Mettons notre seul "2" dans un contexte de:, padding := 2où le contexte est un "GUI Container". Dans ce contexte, la signification de 2 (en pixels ou autre unité graphique) nous offre une estimation rapide de sa sémantique (signification et objectif). Nous pourrions nous arrêter ici et dire que 2 est correct dans ce contexte et qu'il n'y a rien d'autre que nous devons savoir. Cependant, peut-être que dans notre univers logiciel, ce n'est pas toute l'histoire. Il y a plus, mais "padding = 2" en tant que contexte ne peut pas le révéler.

Supposons en outre que 2 en tant que remplissage de pixels dans notre programme est de la variété "default_padding" dans tout notre système. Par conséquent, écrire l'instruction padding = 2n'est pas suffisant. La notion de "défaut" n'est pas révélée. Ce n'est que lorsque j'écris: en padding = default_paddingtant que contexte, puis ailleurs: default_padding = 2que je réalise pleinement une signification meilleure et plus complète (sémantique et objectif) de 2 dans notre système.

L'exemple ci-dessus est assez bon car "2" en soi pourrait être n'importe quoi. Ce n'est que lorsque nous limitons la plage et le domaine de compréhension à «mon programme», où 2 est default_paddingdans les parties GUI UX de «mon programme», que nous avons finalement un sens de «2» dans son contexte approprié. Ici "2" est un nombre "magique", qui est factorisé en une constante symbolique default_paddingdans le contexte de l'interface utilisateur graphique de "mon programme" afin de le faire utiliser comme default_paddingil est compris rapidement dans le contexte plus large du code englobant.

Ainsi, toute valeur de base, dont le sens (sémantique et finalité) ne peut être suffisamment et rapidement compris est un bon candidat pour une constante symbolique à la place de la valeur de base (par exemple le nombre magique).

Aller plus loin

Les nombres sur une échelle peuvent également avoir une sémantique. Par exemple, faites comme si nous faisions un jeu D&D, où nous avons la notion de monstre. Notre objet monstre a une fonctionnalité appelée life_force, qui est un entier. Les nombres ont des significations qui ne sont pas connaissables ou claires sans mots pour fournir un sens. Ainsi, nous commençons par dire arbitrairement:

  • full_life_force: INTEGER = 10 - Très vivant (et indemne)
  • minimum_life_force: INTEGER = 1 - A peine vivant (très blessé)
  • dead: INTEGER = 0 - Dead
  • morts-vivants: INTEGER = -1 - Min morts-vivants (presque morts)
  • zombie: INTEGER = -10 - Max morts-vivants (très morts-vivants)

À partir des constantes symboliques ci-dessus, nous commençons à obtenir une image mentale de la vivacité, de la mort et des "morts-vivants" (et des ramifications ou conséquences possibles) pour nos monstres dans notre jeu D&D. Sans ces mots (constantes symboliques), il ne nous reste que les nombres allant de -10 .. 10. Juste la plage sans les mots nous laisse dans un endroit de confusion possible et potentiellement avec des erreurs dans notre jeu si différentes parties du jeu ont des dépendances sur ce que cette plage de nombres signifie pour diverses opérations comme attack_elvesou seek_magic_healing_potion.

Par conséquent, lorsque vous recherchez et envisagez de remplacer des "nombres magiques", nous voulons poser des questions très précises sur les nombres dans le contexte de notre logiciel et même sur la façon dont les nombres interagissent sémantiquement entre eux.

Conclusion

Passons en revue les questions que nous devons poser:

Vous pourriez avoir un nombre magique si ...

  1. La valeur de base peut-elle avoir une signification ou un objectif particulier dans votre univers logiciel?
  2. Le sens ou le but particulier peut-il probablement être inconnu, inconnaissable, peu clair ou déroutant, même dans son contexte approprié?
  3. Une valeur de base appropriée peut-elle être utilisée incorrectement avec de mauvaises conséquences dans le mauvais contexte?
  4. Une valeur de base incorrecte peut-elle être correctement utilisée avec de mauvaises conséquences dans le bon contexte?
  5. La valeur de base a-t-elle une relation sémantique ou de but avec d'autres valeurs de base dans des contextes spécifiques?
  6. Une valeur de base peut-elle exister à plusieurs endroits de notre code avec une sémantique différente dans chacun, causant ainsi une confusion chez notre lecteur?

Examinez les valeurs de base constantes manifestes autonomes dans votre texte de code. Posez chaque question lentement et avec réflexion sur chaque instance d'une telle valeur. Considérez la force de votre réponse. Souvent, la réponse n'est pas en noir et blanc, mais a des nuances de sens et de but mal compris, de vitesse d'apprentissage et de vitesse de compréhension. Il est également nécessaire de voir comment il se connecte à la machine logicielle qui l'entoure.

En fin de compte, la réponse au remplacement est de répondre à la mesure (dans votre esprit) de la force ou de la faiblesse du lecteur pour établir la connexion (par exemple, «obtenez-le»). Plus ils comprennent rapidement le sens et le but, moins vous avez de «magie».

CONCLUSION: Remplacez les valeurs de base par des constantes symboliques uniquement lorsque la magie est suffisamment grande pour provoquer des bogues difficiles à détecter résultant de confusions.


1
Merci. Fwiw les outils d'analyse statique que mes collègues continuent d'installer se plaignent des nombres magiques - mais comment un outil est-il censé comprendre la sémantique? Le résultat est que TOUTES les valeurs de base sont remplacées par des constantes symboliques. Comme je suis d'accord avec votre conclusion, je trouve cela loin d'être idéal.
Chomeh

17

Un nombre magique est une séquence de caractères au début d'un format de fichier, ou échange de protocole. Ce numéro sert de test de santé mentale.

Exemple: ouvrez n'importe quel fichier GIF, vous verrez au tout début: GIF89. "GIF89" étant le nombre magique.

D'autres programmes peuvent lire les premiers caractères d'un fichier et identifier correctement les GIF.

Le danger est que les données binaires aléatoires puissent contenir ces mêmes caractères. Mais c'est très peu probable.

Quant à l'échange de protocoles, vous pouvez l'utiliser pour identifier rapidement que le «message» actuel qui vous est transmis est corrompu ou non valide.

Les nombres magiques sont toujours utiles.


13
Je ne pense pas que ce soit le nombre magique auquel il faisait référence
Marcio Aguiar

4
Vous devriez peut-être supprimer les balises "format de fichier" et "réseau" que vous avez ajoutées, car il ne parle clairement pas de ces types de nombres magiques.
Landon

9
Il est toujours très utile de savoir que les nombres magiques peuvent faire référence à plus qu'un simple problème de code. -Adam
Adam Davis

3
Si le sujet disait: "Qu'est-ce qu'un nombre magique en termes de code source", alors les balises ne devraient pas être là. Mais il n'a pas précisé cela. Il est donc bon d'avoir mes informations supplémentaires. Je pense que Kyle, Landon et Marcio ont tort.
Brian R. Bondy

4
Il n'y avait également aucun moyen de déterminer celui qu'il cherchait. Depuis que j'étais le premier poste, je ne pouvais pas deviner lequel il cherchait.
Brian R. Bondy

12

En programmation, un "nombre magique" est une valeur à laquelle il faut donner un nom symbolique, mais qui a plutôt été glissé dans le code en tant que littéral, généralement à plusieurs endroits.

C'est mauvais pour la même raison que SPOT (Single Point of Truth) est bon: si vous voulez changer cette constante plus tard, vous devrez parcourir votre code pour trouver chaque instance. Il est également mauvais car il peut ne pas être clair pour les autres programmeurs ce que ce nombre représente, d'où la "magie".

Les gens poussent parfois l'élimination des nombres magiques plus loin, en déplaçant ces constantes dans des fichiers séparés pour servir de configuration. Ceci est parfois utile, mais peut également créer plus de complexité qu'il n'en vaut la peine.


Pouvez-vous être plus précis sur les raisons pour lesquelles l'élimination des nombres magins N'EST PAS toujours bonne?
Marcio Aguiar

Dans les formules mathématiques comme e ^ pi + 1 = 0
Jared Updike

5
Marcio: Quand vous faites des choses comme "const int EIGHT = 8;" puis les exigences changent et vous vous retrouvez avec "const int EIGHT = 9;"
jmucchiello

6
Désolé, mais c'est simplement un exemple de mauvais nom ou une utilisation de base pour la constante.
Kzqai

1
@MarcioAguiar: Sur certaines plateformes, une expression comme (foo[i]+foo[i+1]+foo[i+2]+1)/3peut être évaluée beaucoup plus rapidement qu'une boucle. Si l'on devait remplacer le 3sans réécrire le code en boucle, quelqu'un qui a vu ITEMS_TO_AVERAGEdéfini comme 3pourrait comprendre qu'il pourrait le changer 5et avoir le code en moyenne plus d'éléments. En revanche, quelqu'un qui a regardé l'expression avec le littéral se 3rendrait compte que le 3représente le nombre d'éléments à additionner.
supercat

10

Un nombre magique peut également être un nombre avec une sémantique spéciale codée en dur. Par exemple, j'ai vu une fois un système dans lequel les ID d'enregistrement> 0 étaient traités normalement, 0 lui-même était "nouvel enregistrement", -1 était "c'est la racine" et -99 était "cela a été créé à la racine". 0 et -99 obligerait le WebService à fournir un nouvel ID.

Ce qui est mauvais, c'est que vous réutilisez un espace (celui des entiers signés pour les ID d'enregistrement) pour des capacités spéciales. Peut-être que vous ne voudrez jamais créer un enregistrement avec l'ID 0, ou avec un ID négatif, mais même si ce n'est pas le cas, chaque personne qui regarde le code ou la base de données peut tomber dessus et être confuse au début. Il va sans dire que ces valeurs spéciales n'étaient pas bien documentées.

On peut dire que 22, 7, -12 et 620 comptent aussi comme des nombres magiques. ;-)


10

Un problème qui n'a pas été évoqué avec l'utilisation des nombres magiques ...

Si vous en avez beaucoup, les chances sont raisonnablement bonnes que vous ayez deux objectifs différents pour lesquels vous utilisez des nombres magiques, où les valeurs se trouvent être les mêmes.

Et puis, bien sûr, vous devez changer la valeur ... pour un seul but.


Cela ne semble pas si probable quand on parle de chiffres (du moins pas pour moi), mais je l'ai rencontré avec des chaînes et c'est un succès: vous devez d'abord lire beaucoup de code pour voir où il est utilisé, que vous dois remarquer qu'il est utilisé pour différentes choses ... pas mon passe-temps préféré.
Tomislav Nakic-Alfirevic

4

Je suppose que c'est une réponse à ma réponse à votre question précédente. En programmation, un nombre magique est une constante numérique intégrée qui apparaît sans explication. S'il apparaît à deux emplacements distincts, cela peut entraîner des circonstances dans lesquelles une instance est modifiée et non une autre. Pour ces deux raisons, il est important d'isoler et de définir les constantes numériques en dehors des endroits où elles sont utilisées.


3

J'ai toujours utilisé le terme «nombre magique» différemment, comme une valeur obscure stockée dans une structure de données qui peut être vérifiée comme un contrôle de validité rapide. Par exemple, les fichiers gzip contiennent 0x1f8b08 comme leurs trois premiers octets, les fichiers de classe Java commencent par 0xcafebabe, etc.

Vous voyez souvent des nombres magiques intégrés dans les formats de fichiers, car les fichiers peuvent être envoyés de manière plutôt promiscuité et perdre toutes les métadonnées sur la façon dont ils ont été créés. Cependant, les nombres magiques sont également parfois utilisés pour les structures de données en mémoire, comme les appels ioctl ().

Une vérification rapide du nombre magique avant de traiter le fichier ou la structure de données permet de signaler les erreurs tôt, plutôt que de passer à travers un traitement potentiellement long afin d'annoncer que l'entrée était complète.


2

Il convient de noter que, parfois, vous voulez des numéros «codés en dur» non configurables dans votre code. Il existe un certain nombre de célèbres, dont 0x5F3759DF qui est utilisé dans l'algorithme optimisé de racine carrée inverse.

Dans les rares cas où je trouve la nécessité d'utiliser de tels numéros magiques, je les définis comme const dans mon code et je documente pourquoi ils sont utilisés, comment ils fonctionnent et d'où ils viennent.


1
À mon avis, l'odeur du code de nombre magique se réfère spécifiquement aux constantes inexpliquées . Tant que vous les mettez dans une constante nommée, cela ne devrait pas poser de problème.
Don Kirkby

2

Qu'en est-il de l'initialisation d'une variable en haut de la classe avec une valeur par défaut? Par exemple:

public class SomeClass {
    private int maxRows = 15000;
    ...
    // Inside another method
    for (int i = 0; i < maxRows; i++) {
        // Do something
    }

    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    public int getMaxRows() {
        return this.maxRows;
    }

Dans ce cas, 15000 est un nombre magique (selon CheckStyles). Pour moi, définir une valeur par défaut est correct. Je ne veux pas avoir à faire:

private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;

Cela rend-il la lecture plus difficile? Je n'ai jamais envisagé cela avant d'avoir installé CheckStyles.


Je pense que ce serait correct si le constructeur initialise la valeur. Sinon, si la valeur est initialisée en dehors du constructeur, je la vois simplement comme un problème et comme quelque chose de plus difficile à lire.
Thomas Eding

Je pense que les static finalconstantes sont exagérées lorsque vous les utilisez dans une seule méthode. Une finalvariable déclarée en haut de la méthode est plus lisible à mon humble avis.
Eva

0

@ eed3si9n: Je dirais même que «1» est un nombre magique. :-)

Un principe lié aux nombres magiques est que chaque fait traité par votre code doit être déclaré exactement une fois. Si vous utilisez des nombres magiques dans votre code (comme l'exemple de longueur de mot de passe donné par @marcio, vous pouvez facilement finir par dupliquer ce fait, et lorsque votre compréhension de ce fait change, vous avez un problème de maintenance.


5
Le code IOW doit être écrit comme ceci:factorial n = if n == BASE_CASE then BASE_VALUE else n * factorial (n - RECURSION_INPUT_CHANGE); RECURSION_INPUT_CHANGE = 1; BASE_CASE = 0; BASE_VALUE = 1
Thomas Eding

0

Qu'en est-il des variables de retour?

Je trouve particulièrement difficile la mise en œuvre de procédures stockées .

Imaginez la prochaine procédure stockée (mauvaise syntaxe, je sais, juste pour montrer un exemple):

int procGetIdCompanyByName(string companyName);

Il renvoie l'ID de l'entreprise s'il existe dans une table particulière. Sinon, il renvoie -1. D'une certaine manière, c'est un nombre magique. Certaines des recommandations que j'ai lues jusqu'à présent disent que je devrai vraiment faire quelque chose comme ça:

int procGetIdCompanyByName(string companyName, bool existsCompany);

Soit dit en passant, que devrait-il retourner si l'entreprise n'existe pas? Ok: il définira existesCompany comme false , mais renverra également -1.

L'option Antoher consiste à créer deux fonctions distinctes:

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

Une condition préalable pour la deuxième procédure stockée est donc que la société existe.

Mais j'ai peur de la simultanéité, car dans ce système, une entreprise peut être créée par un autre utilisateur.

En fin de compte, que pensez-vous de l'utilisation de ce type de «nombres magiques» qui sont relativement connus et sûrs pour dire que quelque chose échoue ou que quelque chose n'existe pas?


Dans ce cas spécifique, si la documentation de la fonction indique qu'une valeur de retour négative signifie qu'aucune entreprise n'a été trouvée, il n'y a aucune raison d'utiliser une constante.
Vincent Fourmond

-1

Un autre avantage de l'extraction d'un nombre magique en tant que constante donne la possibilité de documenter clairement les informations commerciales.

public class Foo {
    /** 
     * Max age in year to get child rate for airline tickets
     * 
     * The value of the constant is {@value}
     */
    public static final int MAX_AGE_FOR_CHILD_RATE = 2;

    public void computeRate() {
         if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
               applyChildRate();
         }
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.