Je suis tout à fait favorable à les préfixes bien faits .
Je pense que la notation hongroise (système) est responsable de la plupart des "mauvaises critiques" dont les préfixes font l'objet.
Cette notation est largement inutile dans les langages fortement typés, par exemple en C++ "lpsz" pour vous dire que votre chaîne est un pointeur long vers une chaîne à terminaison nulle, alors que : l'architecture segmentée est de l'histoire ancienne, les chaînes C++ sont par convention des pointeurs vers des tableaux de chars à terminaison nulle, et il n'est pas vraiment difficile de savoir que "nomclient" est une chaîne !
Cependant, j'utilise des préfixes pour spécifier le nom de l'utilisateur. utilisation d'une variable (essentiellement "Apps hongrois", bien que je préfère éviter le terme hongrois en raison de son association mauvaise et injuste avec le système hongrois), et il s'agit d'une fonction très pratique de l'outil gain de temps y Réduction des bogues approche.
J'utilise :
- m pour les membres
- c pour les constantes/readonlys
- p pour pointeur (et pp pour pointeur à pointeur)
- v pour volatile
- s pour le statique
- i pour les index et les itérateurs
- e pour les événements
Où je souhaite faire le type clair, j'utilise des suffixes standard (par exemple, List, ComboBox, etc.).
Cela permet au programmeur de prendre conscience de la utilisation de la variable à chaque fois qu'ils la voient/utilisent. Le cas le plus important est sans doute "p" pour pointeur (parce que l'usage change de var. à var-> et qu'il faut être beaucoup plus prudent avec les pointeurs - NULLs, arithmétique des pointeurs, etc.
Par exemple, vous pouvez utiliser le même nom de variable de plusieurs façons dans une même fonction : (ici un exemple en C++, mais il s'applique également à de nombreux langages)
MyClass::MyClass(int numItems)
{
mNumItems = numItems;
for (int iItem = 0; iItem < mNumItems; iItem++)
{
Item *pItem = new Item();
itemList[iItem] = pItem;
}
}
Vous pouvez voir ici :
- Pas de confusion entre membre et paramètre
- Pas de confusion entre index/iterator et items
- Utilisation d'un ensemble de variables clairement liées (liste d'éléments, pointeur et index) qui évitent les nombreux pièges des noms génériques (vagues) comme "count", "index".
- Les préfixes réduisent la saisie (ils sont plus courts et fonctionnent mieux avec l'autocomplétion) que des alternatives comme "itemIndex" et "itemPtr".
Un autre avantage des itérateurs "iName" est que je n'indexe jamais un tableau avec un mauvais indice, et si je copie une boucle à l'intérieur d'une autre boucle, je n'ai pas besoin de remanier l'une des variables d'indice de la boucle.
Comparez cet exemple simple et irréaliste :
for (int i = 0; i < 100; i++)
for (int j = 0; j < 5; j++)
list[i].score += other[j].score;
(ce qui est difficile à lire et conduit souvent à l'utilisation de "i" là où "j" était prévu)
avec :
for (int iCompany = 0; iCompany < numCompanies; iCompany++)
for (int iUser = 0; iUser < numUsers; iUser++)
companyList[iCompany].score += userList[iUser].score;
(ce qui est beaucoup plus lisible, et supprime toute confusion sur l'indexation. Avec l'auto-complétion dans les IDE modernes, c'est également rapide et facile à taper)
L'avantage suivant est que les extraits de code ne nécessitent aucun contexte pour être compris. Je peux copier deux lignes de code dans un courrier électronique ou un document, et toute personne lisant ce bout de code peut faire la différence entre tous les membres, constantes, pointeurs, index, etc. Je n'ai pas besoin d'ajouter "oh, et faites attention parce que 'data' est un pointeur sur un pointeur", parce qu'il s'appelle 'ppData'.
Et pour la même raison, je n'ai pas besoin de quitter des yeux une ligne de code pour la comprendre. Je n'ai pas besoin de chercher dans le code pour savoir si "data" est un local, un paramètre, un membre ou une constante. Je n'ai pas besoin de déplacer ma main vers la souris pour placer le pointeur sur "data" et attendre qu'une info-bulle (qui parfois n'apparaît jamais) apparaisse. Pour que les programmeurs puissent lire et comprendre le code de manière significative plus rapidement, car ils ne perdent pas de temps à chercher de haut en bas ou à attendre.
(Si vous ne pensez pas que vous perdez du temps à chercher de haut en bas pour résoudre des problèmes, trouvez un code que vous avez écrit il y a un an et que vous n'avez pas regardé depuis. depuis. Ouvrez le fichier et passez à peu près à la moitié du code sans le lire. Voyez jusqu'où vous pouvez lire à partir de ce point avant de ne plus savoir si quelque chose est un membre, un paramètre ou un local. Maintenant, sautez à un autre endroit aléatoire... C'est ce que nous faisons tous à longueur de journée quand nous sommes célibataires le code de quelqu'un d'autre ou que nous essayons de comprendre comment appeler leur fonction)
Le préfixe 'm' permet également d'éviter la notation "this->", qui est (à mon avis) laide et verbeuse, et l'incohérence qu'elle garantit (même si vous faites attention, vous vous retrouverez généralement avec un mélange de "this->data" et de "data" dans la même classe, parce que rien n'impose une orthographe cohérente du nom).
La notation "this" est destinée à résoudre ambiguïté - mais pourquoi quelqu'un écrirait-il délibérément un code qui peut être ambigu ? Ambiguïté sera conduisent tôt ou tard à un bogue. Et dans certains langages, "ceci" ne peut pas être utilisé pour les membres statiques, ce qui vous oblige à introduire des "cas spéciaux" dans votre style de codage. Je préfère avoir une seule règle de codage simple qui s'applique partout - explicite, sans ambiguïté et cohérente.
Le dernier avantage majeur concerne l'Intellisense et l'autocomplétion. Essayez d'utiliser Intellisense sur un formulaire Windows pour trouver un événement - vous devez parcourir des centaines de méthodes de classe de base mystérieuses que vous n'aurez jamais besoin d'appeler pour trouver les événements. Mais si chaque événement avait un préfixe "e", ils seraient automatiquement listés dans un groupe sous "e". Ainsi, le préfixe fonctionne pour regrouper les membres, les constantes, les événements, etc. dans la liste intellisense, ce qui rend beaucoup plus rapide et plus facile de trouver les noms que vous voulez. (Habituellement, une méthode peut avoir environ 20-50 valeurs (locales, params, membres, consts, événements) qui sont accessibles dans sa portée. Mais après avoir tapé le préfixe (je veux utiliser un index maintenant, donc je tape 'i...'), on me présente seulement 2-5 options d'auto-complétion. La "saisie supplémentaire" que les gens attribuent aux préfixes et aux noms significatifs réduit considérablement l'espace de recherche et accélère sensiblement la vitesse de développement).
Je suis un programmeur paresseux, et la convention ci-dessus me permet d'économiser beaucoup de travail. Je peux coder plus rapidement et je fais beaucoup moins d'erreurs car je sais comment chaque variable doit être utilisée.
Arguments contre
Alors, quels sont les inconvénients ? Les arguments typiques contre les préfixes sont :
-
"Les systèmes de préfixes sont mauvais/diaboliques". . Je suis d'accord pour dire que "m_lpsz" et ses semblables sont mal conçus et totalement inutiles. C'est pourquoi je vous conseille d'utiliser une notation bien conçue pour répondre à vos besoins, plutôt que de copier quelque chose qui n'est pas adapté à votre contexte. (Utilisez le bon outil pour le bon travail).
-
"Si je change l'usage de quelque chose, je dois le renommer". . Oui, bien sûr, c'est le but du refactoring, et c'est pourquoi les IDE ont des outils de refactoring pour faire ce travail rapidement et sans douleur. Même sans préfixe, changer l'usage d'une variable signifie presque certainement que son nom sera modifié. devrait à modifier.
-
"Les préfixes m'embrouillent." . Comme tout outil, jusqu'à ce que vous appreniez à l'utiliser. Une fois que votre cerveau s'est habitué aux modèles de dénomination, il filtre automatiquement les informations et la présence des préfixes ne vous dérange plus vraiment. Mais vous devez utiliser un tel schéma de façon intensive pendant une semaine ou deux avant de le rendre vraiment "fluide". Et c'est à ce moment-là que beaucoup de gens regardent leur ancien code et commencent à se demander comment ils ont pu réussir sans un bon système de préfixe.
-
"Je peux juste regarder le code pour résoudre ce problème". . Oui, mais vous n'avez pas besoin de perdre du temps à chercher ailleurs dans le code ou à vous souvenir de chaque petit détail lorsque la réponse se trouve juste à l'endroit où votre regard est déjà fixé.
-
(Certaines) de ces informations peuvent être trouvées en attendant qu'une infobulle apparaisse sur ma variable. . Oui. Lorsque cela est possible, pour certains types de préfixes, lorsque votre code se compile proprement, après une attente, vous pouvez lire une description et trouver instantanément les informations que le préfixe aurait transmises. Je pense que le préfixe est une approche plus simple, plus fiable et plus efficace.
-
"C'est plus de la dactylographie" . Vraiment ? Un caractère entier de plus ? Ou bien si - avec les outils d'autocomplétion de l'IDE, cela réduira souvent la saisie, car chaque caractère préfixe réduit considérablement l'espace de recherche. Appuyez sur "e" et les trois événements de votre classe apparaissent dans intellisense. Appuyez sur "c" et les cinq constantes sont listées.
-
"Je peux utiliser this->
au lieu de m
" . Eh bien, oui, vous pouvez. Mais c'est juste un préfixe beaucoup plus laid et verbeux ! Seulement, il comporte un risque beaucoup plus grand (surtout en équipe) car pour le compilateur, c'est en option et, par conséquent, son utilisation est souvent incohérente. m
d'autre part, est bref, clair, explicite et non facultatif, il est donc beaucoup plus difficile de faire des erreurs en l'utilisant.
21 votes
Je le préfère ; dans les bases de code complexes, il peut être important de savoir quelles variables sont locales et lesquelles ne le sont pas. J'utilise généralement le préfixe plutôt que de forcer this-> qui, à mon avis, représente beaucoup de saisie supplémentaire et est facultatif (alors que le nommage vous forcera à le faire).
6 votes
Vous ne l'avez jamais vu en Ruby à cause de @ pour attribut, et de l'idiome qui consiste à générer des accesseurs de préférence à l'utilisation directe des attributs.
6 votes
Selon PEP 8 Les variables membres non publiques doivent être préfixées par un trait de soulignement en Python (exemple :
self._something = 1
).2 votes
La coloration syntaxique de l'éditeur ne devrait-elle pas être utilisée pour les identifier ?
4 votes
Vous avez bien vu l'équivalent de
this->member
dans le code Python. En Python, ce serait typiquementself.member
et ce n'est pas seulement une convention, c'est requis par la langue.1 votes
Cela peut être intéressant pour vous : github.com/isocpp/CppCoreGuidelines/blob/master/
0 votes
L'utilisation de
this->memberVar
n'est pas seulement une question de style. La norme C++ établit que les membres non dépendants ne sont pas recherchés dans les classes dépendantes. Cela signifie que si vous êtes dans une classe enfant et que vous essayez d'accéder à une variable membre définie dans un modèle de classe parent, vous devrez fournir un nom qualifié pour cette variable.BaseClass<FooBar>::memberVar
ou, si le type de la variable peut dépendre de l'instanciation spécifique, vous n'aurez pas d'autre choix que d'y accéder par l'instance de classe spécifique.this->memberVar
. Voir par exemple stackoverflow.com/a/24368629/4276112