Existe-t-il de bonnes techniques ou de bons tests pour nommer les types?

23

Une question ouverte et délicate, mais c'est un problème auquel je suis toujours confronté:

Les logiciels faciles à entretenir et à utiliser sont bien conçus. Essayer de rendre une conception intuitive signifie nommer vos composants de manière à ce que le prochain développeur puisse déduire la fonction du composant. C'est pourquoi nous ne nommons pas nos classes "Type1", "Type2", etc.

Lorsque vous modélisez un concept réel (par exemple, un client), cela est généralement aussi simple que de nommer votre type après la modélisation du concept réel. Mais lorsque vous construisez des choses abstraites, qui sont plus orientées système, il est très facile de manquer de noms qui sont à la fois faciles à lire et à digérer.

Cela empire (pour moi) en essayant de nommer des familles de types, avec un type de base ou une interface qui décrit ce que les composants doivent faire, mais pas comment ils fonctionnent. Cela conduit naturellement chaque type dérivé à essayer de décrire la saveur de l'implémentation (par exemple IDataConnectionet SqlConnectiondans le .NET Framework), mais comment exprimer quelque chose de compliqué comme "fonctionne par réflexion et recherche d'un ensemble spécifique d'attributs"?

Ensuite, lorsque vous avez finalement choisi un nom pour le type que vous pensez décrire ce qu'il essaie de faire, votre collègue demande "WTF est-ce que cela DomainSecurityMetadataProviderfait réellement ? "

Existe-t-il de bonnes techniques pour choisir un nom bien intentionné pour un composant, ou comment créer une famille de composants sans obtenir de noms confus?

Existe-t-il des tests simples que je peux appliquer à un nom pour mieux comprendre si le nom est "bon" et devrait être plus intuitif pour les autres?

Paul Turner
la source
20
il y a six techniques qui ont fait leurs preuves pour moi: 1) passer beaucoup de temps à inventer des noms 2) utiliser des revues de code 3) n'hésitez pas à renommer 4) passer beaucoup de temps à inventer des noms 5) utiliser des revues de code 6) N'hésitez pas à renommer
moucher
5
@gnat: Veuillez publier votre réponse en tant que réponse afin que nous puissions la voter.
S.Lott
3
J'utilise souvent un thésaurus lors de nouveaux développements pour m'aider à trouver de bons noms.
Dr.Wily's Apprentice
3
J'essaie d'éviter d'appeler quoi que ce soit "Manager". Alan Green et Jeff Atwood soutiennent que le terme est trop utilisé et trop vague pour donner un sens. Je suis d'accord.
Apprenti du Dr Wily le

Réponses:

41

Pour nommer, il existe six techniques qui ont fait leurs preuves pour moi:

  1. passer beaucoup de temps à inventer des noms
  2. utiliser des revues de code
  3. n'hésitez pas à renommer
  4. passer beaucoup de temps à inventer des noms
  5. utiliser des revues de code
  6. n'hésitez pas à renommer

PS. Si votre API doit être publique, ce qui précède s'applique avant cela - car, vous savez,

"Les API publiques, comme les diamants, sont éternelles. Vous avez une chance de bien faire les choses, alors faites de votre mieux ..." (Joshua Bloch, Comment concevoir une bonne API et pourquoi elle est importante )

moucheron
la source
1
Dans le cas où il s'agit d'une API publique, il existe trois techniques supplémentaires que vous pouvez utiliser ...
UncleZeiv
1
@UncleZeiv: comme ....?
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner: 1. passez beaucoup de temps à inventer des noms 2. utilisez des revues de code et 3. n'hésitez pas à renommer
S.Lott
3
Cette réponse m'a convaincu que généralement: non, il n'y a pas de moyen facile de trouver les bons noms. J'essaye seulement des travaux vraiment durs.
Paul Turner
4
7. N'hésitez pas à reconcevoir les types ou les fonctions s'il s'avère impossible de leur attribuer un nom propre. Un code bien conçu peut toujours être correctement nommé.
Joren
8

Mon test de base est de savoir si vous pouvez décrire la fonction de la variable en utilisant uniquement des mots de la variable:

Par exemple, si DomainSecurityMetadataProvider "Fournit des métadonnées de sécurité de domaine" ou "Fournit des métadonnées relatives à la sécurité de domaine", c'est bien.

Cependant, il existe des nuances qui varient d'une personne à l'autre:

Par exemple, pour moi, original_team_code est le code de l'équipe d'origine, tandis que pour quelqu'un d'autre, il peut s'agir du code d'origine de l'équipe. Mon favori personnel était "UnsafeLegacyMutex", que je ne pouvais m'empêcher de lire comme "Ceci est un Mutex hérité qui est dangereux", plutôt que "Ceci est un Mutex pour ThreadUnsafe Legacy Code".

Mon test étendu consiste donc à écrire la variable sur un tableau / wiki / chat, et à faire deviner ce que cela signifie.

deworde
la source
7

Existe-t-il de bonnes techniques pour choisir un nom bien intentionné pour un composant, ou comment créer une famille de composants sans obtenir de noms confus?

Pas vraiment.

Une astuce, cependant, est d'éviter la "voix passive".

"DomainSecurityMetadataProvider" est passif. Il n'y a pas de verbe, ce sont tous des noms et des noms utilisés comme adjectifs.

"ProviderMetadataForDomainSecurity" est plus actif. Il y a un verbe.

La programmation orientée objet est tout (vraiment) nom-verbe. Nom == objet. Verbe == méthode. Ainsi, un nom de classe est généralement très "nominatif". Il est difficile de rompre avec cette habitude et de commencer à insérer des verbes.

Existe-t-il des tests simples que je peux appliquer à un nom pour mieux comprendre si le nom est "bon" et devrait être plus intuitif pour les autres?

Oui. Vous avez défini un excellent test dans votre question. Demandez à d'autres personnes.

Dans les temps anciens, nous appelions cela une "procédure pas à pas de conception". C'était une grosse affaire en sueur dans une méthodologie en cascade. De nos jours, avec les méthodes Agiles, cela devrait être une collaboration ordinaire entre l'auteur et les utilisateurs d'une classe. Cela ne prend pas (et ne devrait pas) prendre beaucoup de temps. Discuter de la conception (et des noms) avant d'écrire les tests (et le code) réduira le facteur d'étonnement et peut empêcher les WTF.

S.Lott
la source
12
Je ne suis pas sûr d'être d'accord avec l'idée de la voix passive. Pour moi, les classes ont plus de sens que les noms.
deworde
7
D'une manière générale, j'essaie de garder mes noms de type dans une voix passive, car cela convient au style nom-verbe de la POO. Je considérerais ProvideMetadataForDomainSecuritycomme un mauvais nom de type. Les noms de méthode sont généralement beaucoup plus faciles à nommer précisément parce que je suis libre d'utiliser des verbes. La restriction de la langue est au cœur du problème.
Paul Turner
Autant j'aime «demander aux gens» comme un véritable test, je dois demander à mes collègues de nommer au moins deux fois par jour. J'espère quelque chose qui ne nécessite pas le temps des autres.
Paul Turner
2
Les classes font du sens que les noms. Le problème est ces classes complexes avec de longues phrases adjectives. Les prépositions peuvent aussi aider.
S.Lott
2
La collaboration est le secret d'un bon logiciel. La collaboration prend du temps. Il n'y a pas de voie royale vers une bonne écriture.
S.Lott
6

Utilisation d'un thésaurus

Très souvent, je ferai référence à un thésaurus lors d'un nouveau développement afin de trouver les mots appropriés pour décrire mes classes et méthodes.

Classes contenant principalement une logique d'opération

J'ai tendance à nommer des classes qui fournissent principalement des méthodes d'opération dans une structure nom-verbe telle que "EntityProvider", "EntityLocator", etc.

Ces classes ne contiennent généralement pas beaucoup d'état.

Classes contenant l'état

Les écrans d'interface utilisateur et les entités de données sont généralement avec état, et je nomme donc simplement ces classes avec un nom ou un motif adjectif-nom.

Exemples: personne, employé, employé actuel, ancien employé

Classes utilitaires

Les classes qui ne contiennent que des méthodes statiques sont généralement considérées comme des classes "utilitaires", donc je les nomme systématiquement avec un suffixe "Utilitaire".

Exemples: NetworkUtilities, FileUtilities

Les tests

Je n'ai pas de bons tests pour décider si quelque chose est mal nommé, mais je suggérerais d'essayer d'utiliser un seul nom et / ou un seul verbe dans le nom, puis de réfléchir si ce nom / verbe décrit exactement ce que vous '' renommer.

Si vous pensez que la classe / méthode ne contient pas plus que le nom, alors cette classe / méthode devra peut-être être refactorisée.

Alan Green et Jeff Attwood ont écrit sur les maux des classes de nommage avec le suffixe "Manager". Ils soutiennent que le terme «gestionnaire» est trop utilisé et trop vague pour exprimer quoi que ce soit de significatif. Je suis d'accord.

L'article de Jeff fournit également une liste de lignes directrices suggérées dans Code Complete de Steve McConnell.

les variables

Récemment, j'ai expérimenté avec des noms de variables / paramètres descriptifs plus longs qui incorporent des prépositions, telles que "Of", "By", "For", etc. Quelques exemples sont présentés ci-dessous:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

Je trouve que cela fonctionne bien avec la fonctionnalité Intellisense de Visual Studio, ce qui facilite la saisie de ces noms longs. Je trouve également qu'il y a moins de duplication des préfixes de nom de variable (par exemple personID, personFirstName, personLastName vs. idOfPerson, firstNameOfPerson, lastNameOfPerson), fournissant un meilleur "hachage" qui rend l'intellisense encore plus utile.

Apprenti du Dr Wily
la source
1
Je vais appuyer le point sur les noms de variable longs, encore une fois, Visual Studio (si vous l'utilisez) en fait une évidence. Il est beaucoup moins dangereux d'avoir des noms de variables longs qui sont explicites que des noms de variables courts où vous devez "réfléchir" ou rechercher ce que signifie réellement le nom. Pensez également au contexte. Je préfère voir "peopleToDelete" que "listOfPeople". Encore une fois, Visual Studio vous indique le type de la variable, pas besoin de l'inclure.
John Bubriski
Je n'aime pas non plus la notation hongroise élaborée que vous avez ajoutée aux noms de variables. Je ne devrais pas avoir à me soucier si une collection d'ID de personne est un List, un tableau IEnumerableou ConcurrentQueue. C'est un tas d'ID que je dois énumérer et le détail de la mise en œuvre de la façon dont ils sont stockés est un bagage mental inutile. Bien que je convienne généralement que si un nom plus long est considérablement plus descriptif, il devrait être préféré à un nom plus court et moins clair.
Allon Guralnek
@Allon - Drôle, j'étais sur le point de réviser ma réponse en fonction du commentaire de SkippyFire. En fait, je suis d'accord avec toi; mon exemple sent la notation hongroise. Ma seule défense est qu'il est facile de lire le code et de comprendre les types de données impliqués sans IDE disponible, comme si je lis à travers un diff de contrôle de source. Ce n'est pas une excuse, cependant. :) Je vais réviser mon exemple pour qu'il ressemble à firstNameOfEmployee, lastNameOfEmployee, etc.
Dr. Wily's Apprentice
2

Ensuite, lorsque vous avez finalement choisi un nom pour le type que vous pensez décrire ce qu'il essaie de faire, votre collègue demande "WTF ce que DomainSecurityMetadataProvider fait réellement?"

Quel genre de nom attendez-vous pour une classe complexe et spécifique au domaine? C'est à peu près aussi bon que ça va devenir sans faire de votre nom de classe une phrase (ce qui fera que tout le monde pensera que vous avez donné trop de responsabilités à une seule classe)

J'envisagerais de supprimer le fournisseur du nom. S'il mentionne spécifiquement les métadonnées, tout le monde sait déjà que vous utilisez la réflexion. Vous pourriez faire un mot plus concis (ou éventuellement changer pour un autre mot - c'est plus un consommateur qu'un fournisseur d'après ce que vous avez écrit)

Brian
la source
Les métadonnées en question ne sont pas dérivées de la réflexion (mais elles décrivent comment traiter les types). Le type implémente une ISecurityMetadataProviderinterface, qui existe un point injectable dans l'infrastructure de sécurité, pour fournir des informations au sous-système. La dénomination est difficile.
Paul Turner
Je considère DomainSecurityMetadataProvidercomme un fournisseur d' DomainSecurityMetadataobjets, où DomainSecurityMetadatase trouvent les métadonnées elles-mêmes. Nom clair et compréhensible. Je n'ai même pas besoin de savoir ce que DomainSecurityMetadatac'est! Ce n'est qu'un objet fourni par ce fournisseur. La simple suppression d'un Providersuffixe n'améliore pas la lisibilité, mais bien au contraire - réduisez-la. Sans ce suffixe, je pense que ce ne sont que des métadonnées (objet conteneur pour certaines métadonnées), mais pas un objet pour obtenir des métadonnées (d'un fournisseur).
Ruslan Stelmachenko
0

Utilisez des métaphores pour décrire des parties du système. Non seulement cela vous fera découvrir de nouvelles analogies, mais cela vous aidera à nommer plus facilement.

(Je suis conscient que ce n'est pas un exemple fort mais de toute façon) Par exemple, vous pouvez appeler une variable ou un type as mailbox, qui sert de file d'attente pour les messages reçus pour une classe.

nimcap
la source
-1

Une chose sur laquelle je serais très ferme, c'est que les noms ne devraient JAMAIS être incorrects. Meilleur exemple, lors d'une refactorisation, beaucoup de code a changé et quelques variables ont commencé à faire référence à autre chose que ce que leur nom suggérait.

Bientôt, un programmeur a passé des siècles et a utilisé des appels de base de données très coûteux pour essayer de récupérer certaines données qui avaient déjà été extraites et stockées. J'ai tout renommé et tout à coup, nous avons pu supprimer une tonne de logique trop compliquée et boguée.

deworde
la source
1
vous devez supprimer cette réponse et la modifier dans votre réponse d'origine
Ryathal
Je pense que c'est une réponse différente de mon autre réponse.
deworde
-1

Espérons que les cas où vous devez réfléchir si longuement aux noms sont rares. Lorsque ces cas se présentent, écrivez simplement un paragraphe expliquant ce que fait la classe. Contrairement aux commentaires en fonction ou aux commentaires au niveau de la fonction, l'objectif principal d'une classe change rarement, de sorte que le risque de dépassement des commentaires est relativement faible. Vous avez donc le luxe d'écrire quelques paragraphes ou même de dessiner ASCII pour expliquer ce que fait la classe.

kizzx2
la source