Je suis assez novice en génie logiciel et j'ai donc écrit un jeu d'échecs comme exercice d'apprentissage. Mon ami a jeté un coup d'oeil et a souligné que mon code ressemblait à
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
alors qu'il a insisté pour qu'il devrait plutôt être
for (int i = 0; i < CHESS_CONST; i++){
for (int j = 0; j < CHESS_CONST; j++){
avec un meilleur nom de symbole que je ne peux pas être dérangé à penser pour le moment.
Maintenant, bien sûr, je sais qu’il faut généralement éviter d’utiliser des nombres magiques, mais je me sens comme depuis
- ce nombre ne changera jamais;
- le nom ne pourrait de toute façon pas être descriptif, car le numéro est utilisé à maintes reprises dans le code; et
- toute personne passant par le code source d'un programme d'échecs doit en savoir assez sur les échecs pour savoir à quoi sert le 8,
il n'y a vraiment pas besoin d'une constante symbolique.
Alors qu'est-ce que vous en pensez? Est-ce excessif, ou devrais-je simplement utiliser la convention et utiliser un symbole?
coding-style
coding-standards
chocolat chocolaté
la source
la source
i
etj
les variables de boucle. Je ne peux pas pour la vie de savoir lequel est censé représenter un rang et lequel est supposé représenter un fichier. Les rangs vont de 1..8 et les fichiers de a..h, mais dans votre cas, les deuxi
etj
vont de 0..7, donc cela ne m'aide pas à voir lequel est lequel. Y a-t-il une crise internationale de pénurie de lettres que je ne connais pas ou qu'est-ce qui ne va pas avec leur changement de nomrank
etfile
?foreach(var rank in Ranks)
. J'envisagerais également de fusionner les deux boucles en une boucle où chaque élément est un tuple (rang, fichier).Réponses:
IMHO votre ami a raison d'utiliser un nom symbolique, bien que je pense que le nom devrait être plus descriptif (comme
BOARD_WIDTH
au lieu deCHESS_CONST
).Même si le nombre ne changera jamais au cours de la vie du programme, il se peut qu’il existe d’autres endroits dans votre programme où le nombre 8 apparaîtra avec une signification différente. Remplacer "8" par
BOARD_WIDTH
où que soit la largeur de la planche et utiliser un autre nom symbolique pour désigner une chose différente rend ces différentes significations explicites, évidentes et votre programme global plus lisible et maintenable. Il vous permet également d'effectuer une recherche globale sur votre programme (ou une recherche de symbole inverse, si votre environnement le permet) au cas où vous auriez besoin d'identifier rapidement tous les endroits du code qui dépendent de la largeur de la carte.Voir également cet ancien article de SE.SE pour une discussion sur la manière de choisir (ou non) de choisir des noms pour les nombres.
En remarque, comme cela a été discuté ici dans les commentaires : si, dans le code de votre programme réel, il importe que la variable fasse
i
référence à des lignes etj
à des colonnes du tableau, ou inversement, il est recommandé de choisir des noms de variables qui faire la distinction claire, commerow
etcol
. L'avantage de tels noms est qu'ils donnent l' impression qu'un code erroné est incorrect.la source
Ok, voici quelques commentaires que j'ai:
Se débarrasser des chiffres magiques est une excellente idée. Il existe un concept appelé DRY, souvent mal représenté, mais l’idée est de ne pas dupliquer la connaissance des concepts de votre projet. Ainsi, si vous avez une classe appelée ChessBoard, vous pouvez conserver une constante appelée BOARD_SIZE ou ChessBoard.SIZE. De cette façon, il n’existe qu’une source unique pour ces informations. En outre, cela aide la lisibilité plus tard:
Même si le nombre ne change jamais, votre programme est sans doute meilleur. Toute personne qui le lit en sait plus sur le code.
Un mauvais nom est pire qu'un non-nom, mais cela ne signifie pas qu'il ne faut pas nommer quelque chose. Il suffit de changer le nom. Ne jetez pas le bébé avec l'eau du bain. : p Le nom peut être descriptif tant que vous comprenez bien ce qu'il décrit. Ensuite, ce concept peut être utilisé pour plusieurs choses différentes.
la source
Ce que vous voulez vraiment, c'est éliminer les références ad nauseum aux constantes, qu'elles soient nommées ou non:
Si vous voulez réellement multiplier la constante en répétant de telles boucles, etc., il est préférable de vous en tenir à
8
.8
se décrit lui-même; ce n'est pas une macro qui représente autre chose.Vous ne le transformerez jamais (TM) en programme d'échecs 9x9 et si vous le faites déjà, la prolifération de 8 ne sera pas la principale difficulté.
Nous pouvons rechercher une base de codes de 150 000 lignes pour le jeton 8 et classer quelles occurrences signifient quoi en secondes.
Le plus important est de modulariser le code afin que la connaissance des échecs soit concentrée dans le moins d'endroits possible. Il vaut mieux avoir un, deux, voire trois modules spécifiques aux échecs dans lesquels se trouve un 8 littéral, que trente-sept modules avec une responsabilité spécifique aux échecs, faisant référence à 8 par un nom symbolique.
Quand ou si cette constante devient une source de tension dans votre programme, vous pouvez facilement la corriger à ce moment-là. Résoudre les problèmes réels qui se produisent maintenant. Si vous ne sentez pas que cela vous gêne, optez pour cet instinct.
Supposons qu'à l'avenir, vous souhaitiez prendre en charge d'autres dimensions de conseil. Dans ce cas, ces boucles devront changer si elles utilisent une constante nommée ou
8
, car les dimensions seront récupérées par une expression telle queboard.width
etboard.height
. Si vous avezBOARD_SIZE
au lieu de8
, ces endroits seront plus faciles à trouver. Donc, c'est moins d'effort. Cependant, vous ne devez pas oublier l'effort de remplacer8
parBOARD_SIZE
. L'effort global n'est pas inférieur. Faire une passe sur le code de changement8
àBOARD_SIZE
, puis une autre pour soutenir d' autres dimensions, n'est pas moins cher que simplement aller de8
l'appui de dimension alternative.Nous pouvons également examiner cette question à partir d’une analyse objective objective des risques et des avantages. Le programme contient maintenant des constantes nues. Si ceux-ci sont remplacés par une constante, il n'y a aucun avantage; le programme est identique. Avec tout changement, il y a un risque non nul. Dans ce cas, c'est petit. Pourtant, aucun risque ne devrait être pris sans bénéfice. Pour "vendre" le changement face à ce raisonnement, nous devons émettre l'hypothèse d'un avantage: un avantage futur qui aidera avec un programme différent: une version future du programme qui n'existe pas maintenant. Si un tel programme est planifié, cette hypothèse et le raisonnement associé sont de bonne foi et doivent être pris au sérieux.
Par exemple, si vous êtes à quelques jours de l'ajout de code supplémentaire qui générera une prolifération accrue de ces constantes, vous pouvez les supprimer. Si ces instances des constantes sont approximativement toutes les instances qui existeront, pourquoi s'en préoccuper?
Si vous travaillez sur des logiciels commerciaux, les arguments de retour sur investissement s'appliqueront également. Si un programme ne se vend pas et que changer certains nombres codés en dur en constantes n'améliorera pas les ventes, vous ne serez pas rémunéré pour l'effort fourni. Le changement n'a aucun retour sur l'investissement en temps. Les arguments de retour sur investissement se généralisent au-delà de l'argent. Vous avez écrit un programme, vous avez investi du temps et de l’effort et vous en avez tiré quelque chose: c’est votre retour, votre "R". Si en effectuant ce changement seul, vous obtenez plus de ce "R", quoi que ce soit, alors bien sûr. Si vous avez des projets de développement, et que ce changement améliore votre "R", idem. Si le changement n'a pas de «R» immédiat ou prévisible, oubliez-le.
la source
8
N'est-ce pas que l'auto-description, c'est un nombre qui pourrait signifier n'importe quoi. Et peut-être qu'ils veulent faire une partie d'échecs 9x9, pourquoi pas? Si vous avez 150 000 lignes de code, vous ne pourrez pas mémoriser ce que chaque8
code signifie dans le code, et même si vous le pouviez, pourquoi le feriez-vous? C'est juste beaucoup de tracas supplémentaire. En ce qui concerne la modularisation, remplacer8
par quelque chose commeNUM_RANKS
cela ne nuit pas à la modularité, en fait, cela aide car cela rend le code plus facile à bricoler.8
parBOARD_SIZE
" " - Le temps que vous avez passé à analyser votre code pour essayer de comprendre ce que chacun8
fait dans votre programme dépasserait probablement le temps passé à remplacer8
par une constante significative au niveau du module.