Je suis tout à fait en faveur des préfixes bien faits .
Je pense que la notation hongroise (système) est responsable de la plupart des "bad rap" que les préfixes reçoivent.
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 long pointeur vers une chaîne terminée par nul, quand: l'architecture segmentée est une histoire ancienne, les chaînes C ++ sont par convention commune des pointeurs vers une terminaison nulle char, et ce n'est pas vraiment difficile de savoir que "customerName" est une chaîne!
Cependant, j'utilise des préfixes pour spécifier l' utilisation d'une variable (essentiellement "Apps hongrois", bien que je préfère éviter le terme hongrois car il a une association mauvaise et injuste avec le système hongrois), et c'est un gain de temps très pratique et approche de réduction des bogues .
J'utilise:
- m pour les membres
- c pour les constantes / readonlys
- p pour le pointeur (et pp pour le pointeur vers le pointeur)
- v pour volatile
- s pour statique
- i pour les index et les itérateurs
- e pour les événements
Là où je souhaite rendre le type clair, j'utilise des suffixes standard (par exemple, Liste, ComboBox, etc.).
Cela rend le programmeur conscient de l' utilisation de la variable chaque fois qu'il la voit / l'utilise. Le cas le plus important est sans doute "p" pour pointeur (car l'utilisation change de var. À var-> et vous devez être beaucoup plus prudent avec les pointeurs - NULL, l'arithmétique du pointeur, etc.), mais tous les autres sont très pratiques.
Par exemple, vous pouvez utiliser le même nom de variable de plusieurs manières dans une seule fonction: (ici un exemple 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:
- Aucune confusion entre membre et paramètre
- Aucune confusion entre index / itérateur 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 (plus courte et fonctionnent mieux avec la saisie semi-automatique) que les alternatives comme "itemIndex" et "itemPtr"
Un autre grand avantage des itérateurs "iName" est que je n'indexe jamais un tableau avec le mauvais index, et si je copie une boucle dans une autre boucle, je n'ai pas à refactoriser l'une des variables d'index de boucle.
Comparez cet exemple d'une simplicité irréaliste:
for (int i = 0; i < 100; i++)
for (int j = 0; j < 5; j++)
list[i].score += other[j].score;
(qui est difficile à lire et conduit souvent à utiliser "i" là où "j" était destiné)
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 la saisie semi-automatique dans les IDE modernes, cette saisie est également rapide et facile)
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 e-mail ou un document, et quiconque lit cet extrait de code peut faire la différence entre tous les membres, constantes, pointeurs, index, etc. Je n'ai pas besoin d'ajouter "oh, et soyez prudent car "data" est un pointeur vers un pointeur ", car il s'appelle" ppData ".
Et pour la même raison, je n'ai pas besoin de sortir les yeux d'une ligne de code pour la comprendre. Je n'ai pas besoin de rechercher dans le code pour trouver si «data» est un paramètre local, un membre ou une constante. Je n'ai pas besoin de déplacer ma main vers la souris pour pouvoir placer le pointeur sur «données», puis attendre qu'une info-bulle (qui n'apparaît parfois jamais) s'affiche. Ainsi, les programmeurs peuvent lire et comprendre le code beaucoup plus rapidement, car ils ne perdent pas de temps à chercher de haut en bas ou à attendre.
(Si vous ne pensez pas perdre de temps à chercher de haut en bas pour résoudre des problèmes, trouvez du code que vous avez écrit il y a un an et que vous n'avez pas regardé depuis. Ouvrez le fichier et sautez à mi-chemin sans le lire. loin, vous pouvez lire à partir de ce point avant de ne pas savoir si quelque chose est un membre, un paramètre ou un local. Maintenant, passez à un autre emplacement aléatoire ... C'est ce que nous faisons tous toute la journée lorsque nous parcourons le code de quelqu'un d'autre ou essayant de comprendre comment appeler leur fonction)
Le préfixe 'm' évite également la notation (IMHO) laide et verbeuse "this->", 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 'data' dans la même classe, car rien n'impose une orthographe cohérente du nom).
«cette» notation est destinée à résoudre l' ambiguïté - mais pourquoi quelqu'un écrirait-il délibérément du code qui peut être ambigu? Ambiguïté va conduire à un bogue tôt ou tard. Et dans certains langages, «ceci» ne peut pas être utilisé pour les membres statiques, vous devez donc 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 est avec Intellisense et l'auto-complétion. Essayez d'utiliser Intellisense sur un formulaire Windows pour trouver un événement - vous devez faire défiler 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 répertoriés dans un groupe sous «e». Ainsi, le préfixage permet de regrouper les membres, les consts, les événements, etc. dans la liste intellisense, ce qui permet de trouver beaucoup plus rapidement et plus facilement les noms que vous voulez. (Habituellement, une méthode peut avoir environ 20 à 50 valeurs (locales, paramètres, 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 ne me propose que 2 à 5 options de saisie semi-automatique.
Je suis un programmeur paresseux, et la convention ci-dessus me fait gagner 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 schémas de préfixes sont mauvais / mauvais" . Je conviens que "m_lpsz" et ses semblables sont mal pensés et totalement inutiles. C'est pourquoi je vous conseillerais d'utiliser une notation bien conçue conçue pour prendre en charge vos besoins, plutôt que de copier quelque chose qui ne convient pas à votre contexte. (Utilisez le bon outil pour le travail).
"Si je change l'usage de quelque chose, je dois le renommer" . Oui, bien sûr que vous faites, c'est ce qu'est le refactoring, et pourquoi les IDE ont des outils de refactoring pour faire ce travail rapidement et sans douleur. Même sans préfixes, changer l'utilisation d'une variable signifie presque certainement que son nom doit être changé.
"Les préfixes me confondent" . 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 filtrera automatiquement les informations et cela ne vous dérangera pas vraiment que les préfixes soient plus là. Mais vous devez utiliser un schéma comme celui-ci solidement pendant une semaine ou deux avant de devenir vraiment "courant". Et c'est à ce moment-là que beaucoup de gens regardent l'ancien code et commencent à se demander comment ils ont pu réussir sans un bon schéma de préfixes.
"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 de celui-ci lorsque la réponse est juste à l'endroit où votre œil est déjà concentré.
(Certaines de) ces informations peuvent être trouvées en attendant simplement qu'une info-bulle apparaisse sur ma variable . Oui. Là où cela est pris en charge, pour certains types de préfixes, lorsque votre code se compile proprement, après une attente, vous pouvez lire une description et trouver les informations que le préfixe aurait transmises instantanément. Je pense que le préfixe est une approche plus simple, plus fiable et plus efficace.
"C'est plus typant" . Vraiment? Un personnage entier de plus? Ou est-ce - avec les outils de saisie semi-automatique IDE, cela réduira souvent la saisie, car chaque caractère de 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 répertoriées.
"Je peux utiliser à la this->
place de m
" . Eh bien, oui, vous pouvez. Mais c'est juste un préfixe beaucoup plus laid et plus bavard! Seulement, il comporte un risque beaucoup plus grand (en particulier dans les équipes) car pour le compilateur, il est facultatif , et donc son utilisation est souvent incohérente. m
d'autre part, il est bref, clair, explicite et non facultatif, il est donc beaucoup plus difficile de faire des erreurs en l'utilisant.