Quelqu'un d'autre trouve-t-il que les classes et méthodes de nommage sont l'une des parties les plus difficiles de la programmation? [fermé]

275

Je travaille donc sur cette classe qui est censée demander de la documentation d'aide à un fournisseur via un service Web. J'essaie de le nommer DocumentRetriever, VendorDocRequester, DocGettermais ils ne sonnent pas bien. J'ai fini par naviguer sur dictionary.com pendant une demi-heure en essayant de trouver un mot adéquat.

Commencer à programmer avec de mauvais noms, c'est comme avoir une très mauvaise journée de cheveux le matin, le reste de la journée descend de là. Tu me sens?

Haoest
la source
2
Pourquoi voudriez-vous une classe, alors que vous n'avez clairement besoin que d'une fonction? Assurez-vous de consulter steve-yegge.blogspot.com/2006/03/… pour le verbe comme problème de nom de classe.
user51568
Ou, avancez et refactorisez quand vous savez enfin comment il devrait être appelé.
Esteban Araya
16
Que nommez-vous?: Méthodes : utilisez des verbes , comme get, set, save, etc. classes et variables : utilisez des noms , comme document, user, context, etc. interfaces : utilisez des adjectifs , comme printable, clonable, iterable, etc. Après avoir lu ce fil, j'aime la suggestion de Spolsky pour les classes et les variables (il utilise des noms) et la suggestion de TravisO pour les méthodes (il utilise des verbes). Aussi ne font pas des objets qui se terminent par « er » .
Daniel Gasull
5
"Il y a deux problèmes difficiles en informatique: l'invalidation du cache, les conventions de dénomination et le débordement silencieux."
Karakuri
6
@karakuri La version que j'ai entendue est "il y a 2 problèmes difficiles en informatique: le nommage et compensé par 1 erreur."
Haoest

Réponses:

121

Ce que vous faites maintenant est bien, et je vous recommande fortement de vous en tenir à votre syntaxe actuelle, à savoir:

contexte + verbe + comment

J'utilise cette méthode pour nommer les fonctions / méthodes, les processus stockés SQL, etc. En respectant cette syntaxe, elle gardera vos volets Intellisense / Code beaucoup plus nets. Vous voulez donc EmployeeGetByID () EmployeeAdd (), EmployeeDeleteByID (). Lorsque vous utilisez une syntaxe plus grammaticalement correcte telle que GetEmployee (), AddEmployee (), vous verrez que cela devient vraiment compliqué si vous avez plusieurs Gets dans la même classe, car les choses non liées seront regroupées.

J'apparais cela à nommer des fichiers avec des dates, vous voulez dire 2009-01-07.log et non 1-7-2009.log car après en avoir un tas, la commande devient totalement inutile.

TravisO
la source
29
Je préfère que le contexte soit déduit du nom de type lors de la dénomination des méthodes ... class EmployeeRepository {void Add (Employee employee); void Get (int id); void GetAll (); void GetAll (filtre Action <FilterCriteria>); } Qu'est-ce que tu penses?
Vyas Bharghava
5
Aide également si vous avez une liste standard de verbes "maison". Donc, c'est toujours Get et pas Load / Read / Retrieve / Select / Find .... etc.
Compte mort le
2
Richard, vous avez raison dans les scénarios de POO, ma réponse a un peu reculé et était plutôt une suggestion de codage générale. Je suppose que techniquement, cela s'applique davantage aux langues non OOP. Employee.Add () et Employee.GetByID () serait la meilleure utilisation dans la POO.
TravisO
6
J'aime l'effet Intellisense de votre suggestion, mais je préfère une approche un peu plus alphabétisée. Je préfère donc Employee.SetSupervisor () à Employee.SupervisorSet () car il se lit (plus comme l'anglais naturel.
Matthew Maravillas
12
Mais @TravisO, cela ne sonne pas bien en anglais. Vous n'obtenez pas d'employé, vous obtenez un employé. Et si vous avez des actions plus complexes impliquant des adjectifs, par exemple InvalidateObsoleteQueries? QueriesInvalidateObsoleteest difficile à lire et n'a pas de sens. En outre, en C #, en particulier avec Resharper, l'ordre alphabétique n'a pas d'importance. Si vous commencez à taper « emp », ReSharper vous donnera GetEmployee, SetEmployeeet même PopulateInactiveEmployeesList.
Ilya Kogan
54

Une leçon que j'ai apprise, c'est que si vous ne trouvez pas de nom pour une classe, il y a presque toujours quelque chose qui ne va pas avec cette classe:

  • tu n'en as pas besoin
  • ça fait trop
Toon Krijthe
la source
13
Ou cela fait trop peu.
user51568
4
Merci, c'était vraiment pertinent pour moi.
Haoest
52

Une bonne convention de dénomination devrait minimiser le nombre de noms possibles que vous pouvez utiliser pour n'importe quelle variable, classe, méthode ou fonction donnée. S'il n'y a qu'un seul nom possible, vous n'aurez jamais de mal à vous en souvenir.

Pour les fonctions et pour les classes singleton, je scrute la fonction pour voir si sa fonction de base est de transformer un genre de chose en un autre. J'utilise ce terme très librement, mais vous découvrirez qu'un nombre ÉNORME de fonctions que vous écrivez prennent essentiellement quelque chose sous une forme et produisent quelque chose sous une autre forme.

Dans votre cas, il semble que votre classe transforme une URL en un document. C'est un peu bizarre de penser de cette façon, mais parfaitement correct, et quand vous commencez à chercher ce modèle, vous le verrez partout.

Lorsque je trouve ce modèle, je nomme toujours la fonction x Fromy .

Puisque votre fonction transforme une URL en un document, je la nommerais

DocumentFromUrl

Ce modèle est remarquablement courant. Par exemple:

atoi -> IntFromString
GetWindowWidth -> WidthInPixelsFromHwnd // or DxFromWnd if you like Hungarian
CreateProcess -> ProcessFromCommandLine

Vous pouvez également l'utiliser UrlToDocumentsi vous êtes plus à l'aise avec cette commande. Que vous disiez x Fromy ou y Tox est probablement une question de goût, mais je préfère l' Fromordre car de cette façon, le début du nom de la fonction vous indique déjà de quel type il retourne.

Choisissez une convention et respectez-la. Si vous faites attention à utiliser les mêmes noms que vos noms de classe dans vos fonctions x Fromy , il sera beaucoup plus facile de vous souvenir des noms que vous avez utilisés. Bien sûr, ce modèle ne fonctionne pas pour tout, mais il fonctionne là où vous écrivez du code qui peut être considéré comme «fonctionnel».

Joel Spolsky
la source
Un joli rappel que dans les langages OOP, les noms de classe n'ont pas toujours besoin d'être des noms mais il est normal qu'ils soient "verbaux" à l'occasion. D'où la raison pour laquelle les praticiens de la POO se font souvent trébucher (comme la personne qui pose la question) car ils insistent trop sur le fait que les cours doivent être une «chose» dans le monde réel.
Ray
7
Le xFromY-Convetion répète essentiellement ce qui est dans le type de retour et la liste des paramètres: Foo fooFromBar (Bar bar). C'est à vous de décider si vous appelez cette cohérence ou redondance.
Lena Schimmel
"Dans votre cas, il semble que votre classe transforme une URL en un document". Depuis quand les classes sont-elles censées "faire" des choses, au lieu de représenter des concepts?
user51568
6
@Brian: c'est seulement redondant en un seul endroit ... à la déclaration. Partout où vous l'utilisez, il est agréable d'avoir un petit rappel des types de données. Rend le code plus lisible sans avoir à revenir à la déclaration.
Joel Spolsky
3
@ stefan- Dans certains langages tels que C # et Java, tout le code doit être encapsulé dans une classe contrairement à C ++. Les fonctions ne sont pas tout à fait des citoyens de première classe dans ces langues si vous voulez modulariser le code. Par conséquent, vous vous retrouvez parfois avec une classe qui pourrait "faire" des choses comme une fonction.
Ray
31

Parfois, il n'y a pas de bon nom pour une classe ou une méthode, cela nous arrive à tous. Souvent, cependant, l'impossibilité de trouver un nom peut être un indice d'un problème avec votre conception. Votre méthode a-t-elle trop de responsabilités? Votre classe résume-t-elle une idée cohérente?

Brad Barker
la source
3
Très bon point, vraiment.
Camilo Martin
27

Fil 1:

function programming_job(){
    while (i make classes){
         Give each class a name quickly; always fairly long and descriptive.
         Implement and test each class to see what they really are. 
         while (not satisfied){
            Re-visit each class and make small adjustments 
         }
    }
}

Fil 2:

while(true){
      if (any code smells bad){
           rework, rename until at least somewhat better
      }
}

Il n'y a pas de Thread.sleep (...) nulle part ici.

krosenvold
la source
24

Je passe aussi beaucoup de temps à m'inquiéter des noms de tout ce qui peut être nommé lorsque je programme. Je dirais cependant que cela rapporte très bien. Parfois, quand je suis coincé, je le laisse pendant un moment et pendant une pause-café, je demande un peu si quelqu'un a une bonne suggestion.

Pour votre classe, je suggère VendorHelpDocRequester.

willcodejavaforfood
la source
1
> VendorHelpDocRequester Bon. En fait, j'ai googlé le demandeur plutôt que le demandeur, les deux semblent être des mots anglais légitimes.
Haoest le
1
Je l'ai fait une ou deux fois aussi :)
willcodejavaforfood
1
Avoir un verbe dans le nom de la classe me semble toujours mal. De plus, cela conduit toujours à une certaine duplication dans l'utilisation (ie:) VendorHelpDocRequester.request(). Je préfère juste la forme plurielle comme `VendorHelpDocs.request () '
Edson Medina
19

Le livre Code Complete de Steve Mcconnell contient un joli chapitre sur le nommage des variables / classes / fonctions / ...

Emile Vrijdags
la source
c'est l'un de mes livres préférés, je le recommande vivement
willcodejavaforfood
2
+1 pour tous ceux qui mentionnent le code complet!
Richard Ev
15

Je pense que c'est un effet secondaire.

Ce n'est pas la dénomination réelle qui est difficile. Ce qui est difficile, c'est que le processus de dénomination vous fait face au fait horrible que vous n'avez aucune idée de ce que vous faites.

Nosredna
la source
12

En fait, je viens d'entendre cette citation hier, à travers le signal contre le bruit blog de 37Signals, et je suis certainement d'accord avec elle:

"Il n'y a que deux choses difficiles en informatique: l'invalidation du cache et le nommage." - Phil Karlton

Jonathan Schuster
la source
simonwillison.net/2007/Jul/5/hard m'a conduit à tbray.org/ongoing/When/200x/2005/12/23/UPI qui m'a conduit à karlton.hamilton.com et à karlton.hamilton.com/quotes /showallquotes.cgi , qui n'inclut pas la citation! (Mais je reconnais le numéro 5 de Scrum.)
Daryl Spitzer
1
"Deux choses difficiles en informatique: l'invalidation du cache, le nommage des choses et les erreurs ponctuelles."
Dan Lugg
7

C'est bien que ce soit difficile. Cela vous oblige à réfléchir au problème et à ce que la classe est censée faire. De bons noms peuvent contribuer à une bonne conception.

JW.
la source
6

D'accord. J'aime garder mes noms de type et mes variables aussi descriptifs que possible sans être trop horriblement longs, mais parfois il y a juste un certain concept pour lequel vous ne pouvez pas trouver un bon mot.

Dans ce cas, cela m'aide toujours à demander l'avis d'un collègue - même si cela n'aide pas en fin de compte, cela m'aide au moins à l'expliquer à haute voix et à faire tourner mes roues.

Daniel Schaffer
la source
6

J'écrivais juste sur les conventions de nommage le mois dernier: http://caseysoftware.com/blog/useful-naming-conventions

L'essentiel:

verbAdjectiveNounStructure - avec Structure et Adjectif comme parties optionnelles

Pour les verbes , je m'en tiens aux verbes d'action: enregistrer, supprimer, notifier, mettre à jour ou générer. De temps en temps, j'utilise «processus» mais uniquement pour faire spécifiquement référence aux files d'attente ou aux retards de travail.

Pour les noms , j'utilise la classe ou l'objet avec lequel on interagit. Dans web2project, il s'agit souvent de tâches ou de projets. Si Javascript interagit avec la page, il peut s'agir d'un corps ou d'un tableau. Le fait est que le code décrit clairement l'objet avec lequel il interagit.

La structure est facultative car elle est unique à la situation. Un écran de liste peut demander une liste ou un tableau. L'une des fonctions principales utilisées dans la liste des projets pour web2project est simplement getProjectList. Il ne modifie pas les données sous-jacentes, juste la représentation des données.

Les adjectifs sont tout autre chose. Ils sont utilisés comme modificateurs du nom. Quelque chose d'aussi simple que getOpenProjects pourrait être facilement implémenté avec un getProjects et un paramètre de commutateur, mais cela a tendance à générer des méthodes qui nécessitent beaucoup de compréhension des données sous-jacentes et / ou de la structure de l'objet ... pas nécessairement quelque chose que vous voulez encourager. En ayant des fonctions plus explicites et spécifiques, vous pouvez complètement envelopper et masquer l'implémentation du code en l'utilisant. N'est-ce pas l'un des points d'OO?

CaseySoftware
la source
4

Plus que simplement nommer une classe, la création d'une structure de package appropriée peut être un défi difficile mais gratifiant. Vous devez envisager de séparer les préoccupations de vos modules et leur rapport avec la vision de l'application.

Considérez maintenant la disposition de votre application:

  • App
    • VendorDocRequester (lire à partir du service Web et fournir des données)
    • VendorDocViewer (utilisez le demandeur pour fournir les documents du fournisseur)

J'oserais deviner qu'il se passe beaucoup de choses dans quelques classes. Si vous deviez refactoriser cela dans une approche plus MVC et permettre à de petites classes de gérer des tâches individuelles, vous pourriez vous retrouver avec quelque chose comme:

  • App
    • VendorDocs
      • Modèle
        • Document (objet simple contenant des données)
        • WebServiceConsumer (gérer les détails dans le service Web)
      • Manette
        • DatabaseAdapter (gérer la persistance à l'aide d'ORM ou d'une autre méthode)
        • WebServiceAdapter (utilisez Consumer pour récupérer un document et le coller dans la base de données)
      • Vue
        • HelpViewer (utilisez DBAdapter pour cracher la documentation)

Ensuite, vos noms de classe s'appuient sur l'espace de noms pour fournir un contexte complet. Les classes elles-mêmes peuvent être intrinsèquement liées à l'application sans avoir besoin de le dire explicitement. En conséquence, les noms de classe sont plus simples et plus faciles à définir!

Une autre suggestion très importante: faites-vous une faveur et prenez une copie des modèles de conception Head First. C'est un livre fantastique et facile à lire qui vous aidera à organiser votre application et à écrire un meilleur code. Apprécier les modèles de conception vous aidera à comprendre que bon nombre des problèmes que vous rencontrez ont déjà été résolus et vous pourrez incorporer les solutions dans votre code.

Mike Griffith
la source
4

Leo Brodie, dans son livre "Thinking Forth", a écrit que la tâche la plus difficile pour un programmeur était de bien nommer les choses, et il a déclaré que l'outil de programmation le plus important est un thésaurus.

Essayez d'utiliser le thésaurus sur http://thesaurus.reference.com/ .

Au-delà, n'utilisez JAMAIS la notation hongroise, évitez les abréviations et soyez cohérent.

Meilleurs vœux.

Rob Williams
la source
1
+1 avec la note que vous ne devez pas utiliser ce qui est appelé système hongrois; L'application hongroise peut parfois être utile, en particulier dans un langage de programmation sans un bon système de frappe.
user51568
Je n'ai jamais entendu parler de la notation hongroise système vs application, mais ce n'est jamais une bonne idée dans n'importe quel environnement - vous devriez toujours nommer en fonction de QUOI, pas COMMENT, et le hongrois est totalement sur la façon dont.
Rob Williams
@RobWilliams Je pense qu'ils faisaient référence à l'article de Joel Spolsky
Alois Mahdal
1
@RobWilliams Aussi, êtes-vous sûr de "Je n'ai jamais entendu parler de X vs Y, mais ce n'est jamais une bonne idée ..." ...? :)
Alois Mahdal
4

En bref:
je conviens que les bons noms sont importants, mais je ne pense pas que vous deviez les trouver avant de les implémenter à tout prix.

Bien sûr, il vaut mieux avoir un bon nom dès le début. Mais si vous ne pouvez pas en trouver une en 2 minutes, renommer plus tard coûtera moins de temps et est le bon choix du point de vue de la productivité.

Long:
En général, il n'est souvent pas utile de penser trop longtemps à un nom avant de l'implémenter. Si vous implémentez votre classe, en la nommant "Foo" ou "Dsnfdkgx", pendant l'implémentation, vous voyez ce que vous auriez dû la nommer.

Surtout avec Java + Eclipse, renommer les choses ne pose aucun problème, car il gère soigneusement toutes les références dans toutes les classes, vous avertit des collisions de noms, etc. Et tant que la classe n'est pas encore dans le référentiel de contrôle de version, je ne le fais pas '' Je pense qu'il n'y a rien de mal à le renommer 5 fois.

Fondamentalement, il s'agit de savoir comment vous pensez de la refactorisation. Personnellement, j'aime ça, même si cela dérange parfois mes coéquipiers, car ils croient en ne faut jamais toucher à un système en cours d'exécution . Et de tout ce que vous pouvez refactoriser, changer de nom est l'une des choses les plus inoffensives que vous puissiez faire.

Lena Schimmel
la source
3

Pourquoi pas HelpDocumentServiceClient une sorte de bouchée, ou HelpDocumentClient ... peu importe que ce soit un fournisseur, le fait est que c'est un client d'un service Web qui traite des documents d'aide.

Et oui, le nommage est difficile.

JoshBerke
la source
3

Il n'y a qu'un seul nom sensible pour cette classe:

HelpRequest

Ne laissez pas les détails de mise en œuvre vous distraire du sens.

Angus Glashier
la source
Un an et demi plus tard, j'étais sur le point de suggérer HelpLibrarypour la classe, mais c'est au moins aussi bon. C'est payant de lire d'abord les réponses!
Jeff Sternal
2

Investissez dans un bon outil de refactoring!

TGnat
la source
lol. Parfois, le refactoring n'est pas la meilleure option (grands projets C ++), mais je l'ai certainement déjà utilisé auparavant. Parfois, je dois juste faire avancer les choses et les noms me viennent plus tard.
Steve S
2

Je m'en tiens aux principes de base: VerbNoun (arguments). Exemples: GetDoc (docID).

Il n'y a pas besoin de fantaisie. Ce sera facile à comprendre dans un an, que ce soit vous ou quelqu'un d'autre.

LJ.
la source
Bien que cela se lit bien, cela s'organise mal car c'est à l'envers. Il vaut mieux dire DocGet () parce que lorsque vous créez également DocAdd () DocRemove () etc., ils apparaîtront tous ensemble dans une liste. Votre méthode montre vraiment à quel point cela devient laid quand vous avez des dizaines de Gets ou autres.
TravisO
Excellente suggestion, TravisO.
Jon Smock
Je n'utiliserais pas un verbe pour une classe normalement.
willcodejavaforfood
2

Pour moi, je ne me soucie pas de la durée d'un nom de méthode ou de classe aussi long que sa description et dans la bonne bibliothèque. Le temps est révolu où vous devez vous rappeler où réside chaque partie de l'API.

Intelisense existe pour toutes les langues principales. Par conséquent, lorsque j'utilise une API tierce, j'aime utiliser son intelligence pour la documentation plutôt que d'utiliser la documentation «réelle».

Dans cet esprit, je peux créer un nom de méthode tel que

StevesPostOnMethodNamesBeingLongOrShort

Long - mais alors quoi. Qui n'utilise pas d'écrans 24 pouces ces jours-ci!

Steve
la source
1

Je dois convenir que la dénomination est un art. Cela devient un peu plus facile si votre classe suit un certain "modèle de desigh" (usine, etc.).

Otávio Décio
la source
1

C'est l'une des raisons d'avoir une norme de codage. Avoir une norme tend à aider à trouver des noms lorsque cela est nécessaire. Cela vous permet de libérer votre esprit pour d'autres choses plus intéressantes! (-:

Je recommanderais de lire le chapitre pertinent du code complet de Steve McConnell ( lien Amazon ) qui contient plusieurs règles pour faciliter la lisibilité et même la maintenabilité.

HTH

à votre santé,

Rob

Rob Wells
la source
1

Non, le débogage est la chose la plus difficile pour moi! :-)

Ragoût S
la source
le débogage revient généralement à poser la bonne question. Il y a ce jeu de nombres où vous devez deviner un nombre de 1 à 1000. Si votre supposition est trop basse ou trop élevée, la console vous le dit et vous n'avez que 10 essais. Que faire?
Haoest
1

DocumentFetcher? C'est difficile à dire sans contexte.

Cela peut aider à agir comme un mathématicien et emprunter / inventer un lexique pour votre domaine au fur et à mesure: choisissez des mots simples et simples qui suggèrent le concept sans l'énoncer à chaque fois. Trop souvent, je vois de longues phrases latinisées qui se transforment en acronymes, ce qui vous oblige à avoir un dictionnaire pour les acronymes de toute façon .

Bacon Darius
la source
1

Le langage que vous utilisez pour décrire le problème est le langage que vous devez utiliser pour les variables, méthodes, objets, classes, etc. De manière lâche, les noms correspondent aux objets et les verbes correspondent aux méthodes. Si vous manquez des mots pour décrire le problème, vous manquez également une compréhension complète (spécification) du problème.

S'il s'agit simplement de choisir entre un ensemble de noms, il doit être guidé par les conventions que vous utilisez pour construire le système. Si vous êtes arrivé à un nouvel endroit, découvert par les conventions précédentes, il vaut toujours la peine de consacrer des efforts à les étendre (correctement, systématiquement) pour couvrir ce nouveau cas.

En cas de doute, dormez dessus et choisissez le premier nom le plus évident, le lendemain matin :-)

Si vous vous réveillez un jour et réalisez que vous aviez tort, changez-le tout de suite.

Paul.

BTW: Document.fetch () est assez évident.

Paul W Homer
la source
1

Je trouve que j'ai le plus de problèmes avec les variables locales. Par exemple, je veux créer un objet de type DocGetter. Je sais donc que c'est un DocGetter. Pourquoi dois-je lui donner un autre nom? Je finis généralement par lui donner un nom comme dg (pour DocGetter) ou temp ou quelque chose de non descriptif.

Jason Baker
la source
1

N'oubliez pas que les modèles de conception (pas seulement ceux du GoF) sont un bon moyen de fournir un vocabulaire commun et leurs noms doivent être utilisés chaque fois que cela correspond à la situation. Cela aidera même les nouveaux arrivants qui connaissent bien la nomenclature à comprendre rapidement l'architecture. Est-ce que cette classe sur laquelle vous travaillez est censée agir comme un proxy ou même une façade?

Herrmann
la source
1

La documentation du fournisseur ne devrait-elle pas être l'objet? Je veux dire, celui-là est tangible, et pas seulement comme une certaine anthropomorphisation d'une partie de votre programme. Ainsi, vous pourriez avoir une VendorDocumentationclasse avec un constructeur qui récupère les informations. Je pense que si un nom de classe contient un verbe, souvent quelque chose a mal tourné.

Svante
la source
1

Je te sens vraiment. Et je sens ta douleur. Chaque nom auquel je pense me semble tout simplement nul. Tout semble si générique et je veux finalement apprendre à injecter un peu de flair et de créativité dans mes noms, en les faisant vraiment refléter ce qu'ils décrivent.

Une suggestion que j'ai est de consulter un thésaurus. Word en a un bon, tout comme Mac OS X. Cela peut vraiment m'aider à sortir la tête des nuages ​​et me donne un bon point de départ ainsi qu'une certaine inspiration.

John Gallagher
la source
0

Si le nom devait s'expliquer à un programmeur profane, il n'est probablement pas nécessaire de le changer.

dreamlax
la source