Je vois des questions similaires à celles-ci en ce qui concerne les noms de paramètres qui correspondent aux propriétés de la classe, mais je ne trouve rien concernant l'utilisation d'un nom de paramètre identique à celui du type de paramètre, à l'exception de la casse en C #. Cela ne semble pas être une violation que je puisse trouver, mais est-ce considéré comme une mauvaise pratique? Par exemple, j'ai la méthode suivante
public Range PadRange(Range range) {}
Cette méthode prend une plage et renvoie une nouvelle plage à laquelle un remplissage a été appliqué. Donc, étant donné le contexte générique, je ne peux pas penser à un nom plus descriptif pour le paramètre. Cependant, cela me rappelle un conseil que j'ai lu en lisant Code Complete à propos de "distance psychologique". Ça dit
La distance psychologique peut être définie comme la facilité avec laquelle deux éléments peuvent être différenciés ... Pendant que vous déboguez, soyez prêt à résoudre les problèmes causés par une distance psychologique insuffisante entre des noms de variable similaires et entre des noms de routine similaires. Lorsque vous construisez du code, choisissez des noms avec de grandes différences afin d’éviter le problème.
La signature de ma méthode a beaucoup de "Portée", donc il semble que cela puisse être un problème en ce qui concerne cette distance psychologique. Maintenant, je vois beaucoup de développeurs faire ce qui suit
public Range PadRange(Range myRange) {}
J'ai personnellement beaucoup de dégoût pour cette convention. L'ajout d'un préfixe "mon" aux noms de variables ne fournit aucun contexte supplémentaire.
Je vois aussi ce qui suit
public Range PadRange(Range rangeToPad) {}
J'aime mieux cela que le préfixe "mon", mais je ne m'en soucie toujours pas. Cela me semble trop verbeux et se lit maladroitement comme un nom de variable. Pour moi, il est entendu que la plage sera complétée en raison du nom de la méthode.
Donc, avec tout cela, mon instinct doit aller avec la première signature. Pour moi, c'est propre. Pas besoin de forcer le contexte quand ce n'est pas nécessaire. Mais est-ce que je fais moi-même ou les futurs développeurs un mauvais service avec cette convention? Suis-je en train de violer une pratique exemplaire?
la source
Range range
c'est bien.Range r
(au moins pour un corps de méthode courte) etRange toPad
.Réponses:
Ne pensez pas trop,
Range range
c'est bien. J'utilise ce type de nommage depuis plus de 15 ans en C #, et probablement beaucoup plus longtemps en C ++, et je n'ai jamais rencontré de véritables inconvénients, bien au contraire.Bien sûr, lorsque vous avez différentes variables locales dans le même périmètre, toutes du même type, il sera probablement utile d'investir un effort mental pour les distinguer correctement.
la source
Wack(Bozo bozoToBeWacked)
comme un exemple de redondance dans le nom de variable qui est amplement exprimée par la méthode elle-même (et donc indésirable selon la question initiale).Wack(Person bozo)
est cependant plus précieux sur le plan sémantique, car cela implique que seuls les bozos soient fustigés.initialRange
. Il est encore très générique mais n’a presque pas le même dégoût quemyRange
.Punch(Bozo punchingBozo, Bozo bozoToBePunched)
. La dénomination détaillée est plus pertinente lorsque vous devez faire la distinction entre plusieurs choses (décrites sémantiquement avec à peu près les mêmes mots). La suggestion de OPRange rangeToPad
n'est pas nécessaire dans son exemple de méthode à un paramètre, mais pourrait être extrêmement nécessaire pour une méthode qui prend plusieursRange
objets.Punch(Bozo source, Bozo target)
ferait le travailJe fais ça tout le temps, ça me donne un grand esprit. S'il s'agit d'un argument passé à un constructeur qui doit être affecté à un membre, mon membre sera également nommé range et l'affectation sera
Et j'aurais typiquement une propriété appelée Range.
Ils sont tous la même chose, ne différant que par leur contexte, il est donc logique de conserver un seul nom et vous ne devez vous souvenir que d’un seul nom. C'est une chose, les différences sont purement techniques.
Vous devriez être strict avec des membres pleinement qualifiés avec "ceci". Cependant, c’est à quoi sert StyleCop.
Note de côté StyleCop
Controverse garantie!
Pour ceux qui défendent l'utilisation de "ceci": j'ai vu _, m, m_ et rien du tout. Le langage lui-même nous offre un moyen parfaitement clair et sans ambiguïté, universellement reconnaissable, d'indiquer que nous traitons avec un membre du groupe. Pourquoi voudriez-vous inventer votre propre chemin qui mutile des noms déjà parfaits?
La seule raison pour laquelle je peux penser que c’est une habitude héritée de l’ère C, alors que c’était logique de le faire parce qu’il n’y avait pas d’autre moyen.
"Ce sont plus de personnages!" Sérieusement? "Le temps de compilation va monter en flèche!" Sérieusement? "Je vais devoir lever mon petit doigt quand je le tape!". Comme si le temps de frappe avait une signification dans le temps de développement total.
Je reconnais que tout style différent de celui auquel vous êtes habitué suscitera une certaine opposition. Mais il est difficile de discuter avec cela systématiquement. Voici comment cela fonctionne pour moi: Avant d'exécuter un nouveau fichier de code, j'exécute StyleCop et il trouvera un certain nombre de membres dépourvus du qualificatif "this". Je mets "ceci". dans le presse-papiers, géré par les membres et inséré. Aucun effort du tout.
StyleCop fait beaucoup plus que cela (haha). Il existe de nombreuses façons pour un développeur (uniquement en ce qui concerne le formatage du code) de frustrer le travail de maintenance de son successeur. StyleCop empêche la plupart d'entre eux. C'est inestimable.
Si vous êtes novice: cela vous fait généralement râler pendant une semaine ou deux et ensuite vous allez l'adorer.
la source
this
sauf si nécessaire. C'est juste du bruit autrement. Utiliser_range
pour le champ etthis
n'est jamais nécessaire sauf dans les méthodes d'extension._
est préférable au bruit dethis.
? Je dirais que l’une a une signification imposée par le langage (et a généralement une coloration syntaxique) tandis que l’autre n’a pas.Mon auto-guidage sur les méthodes de nommage, les paramètres et les variables est assez simple:
Ainsi, la signature de la méthode optimale, à mon avis, serait:
Raccourcir le nom de la méthode est explicite.
Le nom du paramètre
toPad
indique immédiatement au lecteur que ce paramètre sera probablement modifié sur place en étant rempli, puis renvoyé. En revanche, aucune hypothèse ne peut être faite sur une variable nomméerange
.En outre, dans le corps même de la méthode, toutes les autres
Range
variables introduites devraient (devraient) être nommées en fonction de leur intention. Vous pouvez donc vous conformerpadded
etunpadded
... voustoPad
conformer à ces conventions de nommage, mais vousrange
démarquez et ne gélifie pas.la source
padded
/unpadded
sonne bien pour les variables immuables locales. Mais s'il existe untoPad
paramètre mutable , le nomtoPad
ne tient plus après le remplissage (à moins que le résultat ne soit renvoyé immédiatement). Je préférerais m'en tenir àRange range
ces cas.result
. Il est modifié et renvoyé . Le dernier ressort clairement du nom et le premier suit, car renvoyer un argument non modifié n’a aucun sens.Pad
méthode retourne aRange
. Pour moi, cela implique que celui que j'ai transmis sera préservé, non modifié sur place, et qu'un nouveau, capitonné,Range
sera renvoyé. .Pad(toPad)
se sent un peu mal à mon humble avis. Vous faites un bon point de défendre votre point de vue si. Vous obtenez un +0 de moi! :)Pour nommer les éléments de code (types, variables, fonctions, etc.), la question clé à se poser est:
Si je fais une faute de frappe, le compilateur va-t-il me la trouver?
Le pire type de bogue typo est celui où le code est compilé et exécuté, mais donne un comportement différent de celui auquel vous vous attendez, pour des raisons subtiles. Et comme cela est dû à une faute de frappe, il est généralement très difficile de voir quand vous inspectez le code. Si une faute de frappe arrête la compilation du code, le compilateur marque la ligne à l'origine du problème et vous pouvez facilement le trouver et le résoudre.
Pour votre situation où le type et la variable ne diffèrent que par la capitalisation, ce sera toujours le cas. (Ou presque toujours - avec un effort suffisant, je suis sûr que vous pourriez le faire fonctionner, mais vous devriez vraiment essayer.) Donc je pense que vous êtes OK ici.
Si vous aviez deux variables, méthodes, fonctions ou propriétés dans la portée actuelle, appelez
range
etRange
. Dans ce cas, le compilateur le laissera probablement passer et vous obtiendrez un comportement inattendu au moment de l'exécution. Notez que c'est deux tout de ces types d'éléments de code, non seulement « deux variables » ou « deux fonctions » - tous ceux -ci peuvent être implicitement à l'autre, ce qui entraîne un carnage lors de son exécution. Vous pourriez recevoir des avertissements, mais vous ne pouvez rien garantir de plus. Vous avez des problèmes similaires si vous aviez deux types déclarés appelésrange
etRange
.Notez également qu'il en va de même pour le style de notation hongrois , où les noms sont précédés d'un ou de plusieurs caractères pour en dire plus sur ce qu'il est. Si vous avez une variable appelée
Range
et un pointeur appeléPRange
, il est facile de rater accidentellement leP
, par exemple. C # devrait comprendre cela, mais C et C ++ ne vous donneront tout au plus qu'un avertissement. Ou plus inquiétant, supposons que vous ayez une version double appeléeDRange
et que vous sous-échantillonniez celle-ci à une version flottante appeléeFRange
. Utilisez le flottant par accident (ce qui est facile puisque les touches sont adjacentes sur un clavier) et votre code fonctionnera plutôt bien , mais il tombera de manière étrange et imprévisible lorsque le processus sera à court de résolution et de débordement.Nous ne sommes plus dans les temps où nous avions des limites de nommage de 8 caractères, ou 16 caractères, ou quelle que soit la limite arbitraire. J'ai parfois entendu des novices se plaindre de noms de variables plus longs, ce qui rend le codage plus long. Ce ne sont que des novices qui s'en plaignent. Les développeurs sérieux savent que ce qui prend vraiment du temps, c'est de trouver des bugs obscurs - et le mauvais choix du nom est un moyen classique de vous laisser tomber dans ce trou particulier.
la source
Une anecdote que je voudrais ajouter: bien que
Range range
ce soit syntaxiquement légal, cela pourrait rendre les choses plus difficiles à déboguer ou à refactoriser. Vous recherchez cette variable nommée "range" dans un fichier contenant beaucoup de variables de type Range? Vous devrez peut-être faire plus de travail plus tard à la suite de ce choix de nom.Ceci dépend en grande partie du contexte. S'il s'agit d'un fichier de 30 lignes, mes déclarations n'interviennent pas vraiment.
la source
grep
est un excellent outil, mais ce n'est pas un outil de refactoring. Et des outils de refactoring existent sur toutes les plateformes de développement que j'ai utilisées. (OS X, Ubuntu, Windows).Je pense que vous pouvez utiliser aujourd'hui
Range range
pour une raison: la coloration syntaxique. Les IDE modernes mettent généralement en évidence les noms de types et les noms de paramètres dans des couleurs différentes . De plus, un type et une variable ont une "distance logique" considérable à ne pas confondre facilement.Si ce n'était pas le cas, je considérerais un nom différent ou essayerais d'activer un plugin / une extension capable de faire cette coloration syntaxique.
la source
Quand une fonction est générique, il va de soi que les paramètres seront génériques et devraient donc avoir des noms génériques.
Ce n’est pas ce que vous dites, mais j’ai vu des fonctions qui exécutent une fonction générique dont les noms de paramètres sont trompeurs. Comme
Le nom de la fonction semble très générique, comme cela pourrait être appliqué à de nombreuses chaînes dans de nombreuses situations. Mais le nom du paramètre est étrangement spécifique, ce qui me fait me demander si le nom de la fonction est trompeur ou ... quoi?
Donc, bien sûr, au lieu de dire Range, vous pouvez dire Range rangeToPad. Mais quelles informations cela ajoute-t-il? Bien sûr, c'est la gamme à pad. Quoi d'autre serait-il?
Ajouter un préfixe arbitraire, "mon" ou "m_" ou autre, ne donne aucune information supplémentaire au lecteur. Lorsque j'ai utilisé des langages dans lesquels le compilateur ne permet pas à un nom de variable d'être identique à un nom de type - avec ou sans sensibilité à la casse - j'ai parfois mis un préfixe ou un suffixe, juste pour le faire compiler . Mais c'est juste pour satisfaire le compilateur. On pourrait faire valoir que même si le compilateur peut distinguer, cela facilite la tâche du lecteur humain. Mais wow, en Java, j'ai écrit des déclarations du type "client client = nouveau client ();" un milliard de fois et je ne l'ai jamais trouvé déroutant. (Je l'ai toujours trouvé un peu redondant et j'aime assez cela en VB, vous pouvez simplement dire "client faible en tant que nouveau client" et vous n'avez pas à donner le nom de la classe deux fois.)
Je m'oppose fortement aux noms génériques lorsqu'il y a deux instances ou plus du même type dans la même fonction. EN PARTICULIER paramètres. Comme:
Quelle est la différence entre range1 et range2? Comment suis-je censé savoir? Si c'est quelque chose où ils sont vraiment deux valeurs génériques et interchangeables, d'accord, comme
Je m'attendrais à ce que cela retourne true si les plages se chevauchent et false si elles ne le font pas, elles sont donc génériques et interchangeables.
Mais s'ils sont différents, donnez-moi un indice en quoi ils sont différents! Je travaillais récemment sur un programme qui avait récemment une classe "Lieu" pour stocker des données sur des lieux géographiques, et avec des variables de ce type nommées "p", "lieu", "lieu2", "monPlace", etc. Les noms m'aident vraiment à déterminer lequel est lequel.
la source