Nommer les classes - Comment éviter d'appeler tout un «<WhatEver> Manager»? [fermé]

1189

Il y a longtemps, j'ai lu un article (je crois une entrée de blog) qui m'a mis sur la "bonne" piste pour nommer les objets: Soyez très très scrupuleux pour nommer les choses dans votre programme.

Par exemple, si mon application gérait (en tant qu'application commerciale typique) des utilisateurs, des entreprises et des adresses, j'aurais un User, un Companyet une Addressclasse de domaine - et probablement quelque part un UserManager, un CompanyManageret un AddressManagerapparaîtraient pour gérer ces choses.

Alors, pouvez-vous dire ce que ceux UserManager-ci CompanyManageret AddressManagerfaire? Non, car Manager est un terme très très générique qui correspond à tout ce que vous pouvez faire avec vos objets de domaine.

L'article que j'ai lu recommandait d'utiliser des noms très spécifiques. S'il s'agissait d'une application C ++ et que le UserManagertravail consistait à allouer et à libérer les utilisateurs du tas, il ne gérerait pas les utilisateurs mais protégerait leur naissance et leur mort. Hmm, on pourrait peut-être appeler ça un UserShepherd.

Ou peut-être que le UserManagertravail consiste à examiner les données de chaque objet utilisateur et à signer les données cryptographiquement. Ensuite, nous aurions un UserRecordsClerk.

Maintenant que cette idée m'est restée, j'essaie de l'appliquer. Et trouvez cette idée simple incroyablement difficile.

Je peux décrire ce que font les classes et (tant que je ne glisse pas dans un codage rapide et sale) les classes que j'écris font exactement une chose. Ce qui me manque pour passer de cette description aux noms, c'est une sorte de catalogue de noms, un vocabulaire qui mappe les concepts aux noms.

En fin de compte, j'aimerais avoir quelque chose comme un catalogue de modèles dans mon esprit (les modèles de conception fournissent souvent facilement les noms d'objets, par exemple une usine )

  • Factory - Crée d'autres objets (dénomination tirée du modèle de conception)
  • Shepherd - Un berger gère la durée de vie des objets, leur création et leur arrêt
  • Synchroniseur - Copie des données entre deux ou plusieurs objets (ou hiérarchies d'objets)
  • Nanny - Aide les objets à atteindre l'état "utilisable" après leur création - par exemple en les connectant à d'autres objets

  • etc.

Alors, comment gérez-vous ce problème? Avez-vous un vocabulaire fixe, inventez-vous de nouveaux noms à la volée ou envisagez-vous de nommer des choses pas si importantes ou erronées?

PS: je suis également intéressé par des liens vers des articles et des blogs traitant de la question. Pour commencer, voici l'article original qui m'a fait réfléchir: Nommer des classes Java sans 'Manager'


Mise à jour: résumé des réponses

Voici un petit résumé de ce que j'ai appris de cette question entre-temps.

  • Essayez de ne pas créer de nouvelles métaphores (Nanny)
  • Jetez un œil à ce que font les autres frameworks

Autres articles / livres sur ce sujet:

Et une liste actuelle des préfixes / suffixes de noms que j'ai collectés (subjectivement!) À partir des réponses:

  • Coordinateur
  • Constructeur
  • Écrivain
  • Lecteur
  • Gestionnaire
  • Récipient
  • Protocole
  • Cible
  • Convertisseur
  • Manette
  • Vue
  • Usine
  • Entité
  • Seau

Et un bon conseil pour la route:

N'obtenez pas la paralysie des noms. Oui, les noms sont très importants, mais ils ne le sont pas suffisamment pour perdre énormément de temps. Si vous ne pouvez pas trouver un bon nom en 10 minutes, passez à autre chose.

temps42
la source
11
Il appartient au wiki de la communauté car il n'y a pas de «meilleure» réponse. C'est une discussion.
DOK
13
C'est contre-intuitif. Ne devraient-ils pas appeler cela un forum? Je pense qu'un wiki serait pour une collection de faits, pas d'opinions.
AaronLS
78
Merci d'avoir gardé cette mise à jour - mais ugh, cette dernière astuce est un conseil terrible! Si vous ne pouvez pas penser à un bon nom en 10 minutes, il y a probablement quelque chose qui ne va pas avec votre classe. (Avec les mises en garde standard: 1) le parfait est l'ennemi du bien, 2) L'expédition est une fonctionnalité - rappelez-vous simplement que vous contractez des dettes techniques.)
Jeff Sternal
11
Si vous n'arrivez pas à trouver un bon nom en 10 minutes, demandez de l'aide à votre collègue. N'abandonnez pas.
9
Si vous ne pouvez pas trouver un bon nom en 10 minutes, essayez de l'expliquer à vos collègues; ils pourraient penser à un bon nom (user338195), mais essayer de l'expliquer vous aidera probablement à découvrir ce qui ne va pas ( Jeff ).
WillC

Réponses:

204

J'ai posé une question similaire , mais dans la mesure du possible, j'essaie de copier les noms déjà dans le framework .NET , et je cherche des idées dans les frameworks Java et Android .

Il semble Helper, Manageret Utilsont les noms incontournables vous joindrez pour la coordination des classes qui ne contiennent pas d' état et sont généralement des procédures et statiques. Une alternative est Coordinator.

Vous pourriez obtenir particulièrement violet prosey avec les noms et aller pour des choses comme Minder, Overseer, Supervisor, Administratoret Master, mais comme je le disais , je préfère le garder comme les noms de cadres que vous êtes habitué.


Certains autres suffixes courants (si c'est le terme correct) que vous trouvez également dans le framework .NET sont:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
Chris S
la source
4
Je les aime beaucoup. Ils ne tombent pas dans le piège des métaphores mauvaises ou inconnues car ils sont déjà utilisés par le .NET Framework. Il pourrait être intéressant de regarder d'autres bibliothèques (Java) également pour plus d'informations sur ce qui est couramment utilisé.
froh42
Je voudrais suggérer Conductor, comme le chef d'orchestre musical. C'est sûrement un rôle important, selon la nature des collaborations que vous devez "mener" (d'autres objets étant des acteurs très spécialisés qui devraient répondre à un commandement centralisé et ne pas trop se soucier de tous les autres collaborateurs).
heltonbiker
1
Je ne crois pas que la solution pour les classes -er soit de trouver un nom différent. Comme je l'ai lu dans de nombreux autres articles et que j'essaie d'apprendre la réponse, c'est que vous devez changer l'architecture, pas seulement le nom utilisé.
Michael Ozeryansky
115

Vous pouvez jeter un œil à source-code-wordle.de , j'y ai analysé les suffixes les plus fréquemment utilisés des noms de classe du framework .NET et d'autres bibliothèques.

Les 20 premiers sont:

  • attribut
  • type
  • assistant
  • collection
  • convertisseur
  • gestionnaire
  • Info
  • fournisseur
  • exception
  • un service
  • élément
  • directeur
  • nœud
  • option
  • usine
  • le contexte
  • article
  • designer
  • base
  • éditeur
Markus Meyer
la source
147
Dans une entreprise en particulier il y a longtemps, je connaissais un ingénieur tellement fatigué de la pléthore absurde et croissante de règles de suffixes qui affligent l'entreprise avec laquelle il a mis fin à chaque classe avec défi Thingy.
8
Cette liste de noms en elle-même n'est pas si utile sans le contexte auquel le suffixe doit être appliqué.
Fred
65

Je suis pour les bons noms, et j'écris souvent sur l'importance de faire très attention lors du choix des noms pour les choses. Pour cette même raison, je me méfie des métaphores pour nommer les choses. Dans la question d'origine, «usine» et «synchroniseur» ressemblent à de bons noms pour ce qu'ils semblent signifier. Cependant, "berger" et "nounou" ne le sont pas, car ils sont basés sur des métaphores . Une classe de votre code ne peut pas être littéralement une nounou; vous l'appelez une nounou parce qu'elle s'occupe d'autres choses comme une nounou dans la vraie vie s'occupe de bébés ou d'enfants. C'est OK dans un discours informel, mais pas OK (à mon avis) pour nommer des classes dans du code qui devra être maintenu par qui sait qui sait quand.

Pourquoi? Parce que les métaphores dépendent de la culture et souvent aussi de l'individu. Pour vous, nommer une nounou de classe peut être très clair, mais ce n'est peut-être pas si clair pour quelqu'un d'autre. Nous ne devons pas nous y fier, à moins que vous n'écriviez du code uniquement pour un usage personnel.

Dans tous les cas, la convention peut faire ou défaire une métaphore. L'utilisation de "factory" elle-même est basée sur une métaphore, mais qui existe depuis un certain temps et qui est actuellement assez bien connue dans le monde de la programmation, donc je dirais que son utilisation est sûre. Cependant, "nounou" et "berger" sont inacceptables.

CesarGon
la source
10
Cet argument se décompose vraiment en ce que évidemment Factory lui-même est une métaphore. Souvent, les métaphores clarifient vraiment à quoi un objet peut être bon, alors qu'être vague ou générique garantit automatiquement que la seule façon de comprendre ce que fait le code est de le lire entièrement! Le pire des cas.
Kzqai
1
+1 pour éviter les noms «mignons». Je pense que c'est génial d'être aussi direct avec la langue que possible. (Bien sûr, ce n'est pas toujours facile d'être direct, succinct, précis et sans ambiguïté à la fois…)
andrewf
1
Un choix inventif de verbe + "er" sera généralement plus clair pour les classes concrètes qu'une analogie colorée. De nouvelles abstractions, en revanche - des choses qui sont un nouveau concept, un nouveau "genre de chose" plutôt que juste une nouvelle "chose" - fonctionnent souvent bien comme métaphores ("haricots" de Java, "lentilles" de Haskell, interface graphique) "fenêtres", "les promesses" de nombreuses langues). Cependant, la plupart des bases de code n'auront pas de véritables inventions de ce genre.
Malnormalulo
51

Nous pourrions faire sans xxxFactory, xxxManagerou les xxxRepositoryclasses si nous avons modélisé correctement le monde réel:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)

herzmeister
la source
11
Comment arriveriez-vous à des univers parallèles et à des dimensions alternatives?
tster du
23
C'est facile: Omniverse.Instance.Dimensions ["Ours"]. Univers ["Ours"]. Galaxies ... ... ok ok j'admets que cela nécessiterait une recompilation. ;-)
herzmeister
73
Mise à jour: cela a été ajouté dans .NET 4.0:; Universe.Instance.ToParallel())
Connell
2
Enfreint la loi de Demeter!
Jonas G. Drange
13
Ce sont des objets et des membres, pas des noms de classe
Harry Berry
39

Cela ressemble à une pente glissante vers quelque chose qui serait publié sur le site quotidien, "ManagerOfPeopleWhoHaveMortgages", etc.

Je suppose qu'il est juste qu'une classe Manager monolithique ne soit pas une bonne conception, mais utiliser 'Manager' n'est pas mauvais. Au lieu de UserManager, nous pourrions le décomposer en UserAccountManager, UserProfileManager, UserSecurityManager, etc.

«Manager» est un bon mot car il montre clairement qu'une classe ne représente pas une «chose» du monde réel. 'AccountsClerk' - comment suis-je censé dire s'il s'agit d'une classe qui gère les données des utilisateurs ou représente quelqu'un qui est commis aux comptes pour son travail?

Mr. Boy
la source
8
Qu'en est-il de UserAccounter, UserProfiler et UserSecurer? Si vous vous débarrassez de Manager, vous êtes obligé de trouver la définition spécifique, ce qui, je pense, est une bonne chose.
Didier A.
10
Qu'en est-il de UserAccount, UserProfile, UserSecurity oO?
Clime
3
Je l'appellerais "MortageOwnersManager"
volter9
Parfois, le domaine a des noms spécifiques. Comme "MortageHolder" qui pourrait être mieux que "MortageOwner"
borjab
24

Lorsque je pense à utiliser Managerou Helperdans un nom de classe, je considère que c'est une odeur de code qui signifie que je n'ai pas encore trouvé la bonne abstraction et / ou que je viole le principe de la responsabilité unique , donc refactorisation et plus d'efforts dans la conception rend souvent le nommage beaucoup plus facile.

Mais même les classes bien conçues ne se nomment pas (toujours) et vos choix dépendent en partie de la création de classes de modèle économique ou de classes d'infrastructure technique.

Les classes de modèle d'entreprise peuvent être difficiles, car elles sont différentes pour chaque domaine. Il y a certains termes que j'utilise beaucoup, comme Policypour les classes de stratégie dans un domaine (par exemple, LateRentalPolicy), mais ceux-ci découlent généralement de la tentative de créer un " langage omniprésent " que vous pouvez partager avec les utilisateurs professionnels, de la conception et de la dénomination des classes afin qu'elles modélisent le réel -des idées, des objets, des actions et des événements mondiaux.

Les classes d'infrastructure technique sont un peu plus faciles, car elles décrivent des domaines que nous connaissons très bien. Je préfère incorporer des noms de modèle de conception dans les noms de classe, comme InsertUserCommand, CustomerRepository,ou SapAdapter.je comprends le souci de communiquer l'implémentation plutôt que l'intention, mais les modèles de conception associent ces deux aspects de la conception de classe - au moins lorsque vous traitez avec une infrastructure, où vous voulez que la conception de l' implémentation doit être transparente même lorsque vous cachez les détails.

Jeff Sternal
la source
1
J'aime vraiment l'idée d'utiliser le Policysuffixe pour les classes contenant la logique métier
jtate
+1 pour avoir mentionné l'odeur de code associée à des noms comme "Manager" et "Helper". Je trouve que si je n'ai pas de noms clairs pour les choses, cela découle généralement au moins en partie d'un flou dans ma compréhension du domaine, qu'il soit commercial ou technique. Presque de manière équivalente, cela pourrait signifier que je suis juste en train de rompre les cours de manière réactive parce qu'ils "sont devenus trop gros" - ce qui pour moi est également un signe de modélisation inadéquate. Cela devrait être la réponse la plus votée.
nclark
10

Être au fait des modèles définis par (disons) le livre GOF et nommer les objets après ceux-ci me permet de nommer les classes, de les organiser et de communiquer l'intention. La plupart des gens comprendront cette nomenclature (ou du moins une grande partie de celle-ci).

Brian Agnew
la source
Fowler est une bonne référence pour moi, mais le GOF est une excellente recommandation.
Lazarus
Pardonnez mon ignorance. De quel livre Fowler parlez-vous?
Brian Agnew
19
Hmm, parfois cela fonctionne (par exemple, comme une usine ou une stratégie), mais à d'autres moments, je pense que cela communique le mode de mise en œuvre (j'ai utilisé un modèle!) Plus que l'intention et le travail de la classe. Par exemple, la chose la plus importante d'un Singleton est ce qu'il représente - et non pas qu'il s'agit d'un Singleton. Une dénomination stricte après les modèles utilisés ressemble à une dénomination stricte après les types utilisés. Par exemple, la notation hongroise mal appliquée par le groupe des systèmes Windows (décrivant le type de données C au lieu de "type d'intention")
froh42
1
Pour les classes d'infrastructure technique, il est généralement souhaitable de rendre l'implémentation transparente - et la plupart des noms de modèle de conception canonique communiquent à la fois l'implémentation et l'intention. Les classes de modèle de domaine sont cependant une autre affaire.
Jeff Sternal
10

Si je ne peux pas trouver un nom plus concret pour ma classe que XyzManager, ce serait un point pour moi de reconsidérer s'il s'agit vraiment d'une fonctionnalité qui appartient à une classe, c'est-à-dire une «odeur de code» architecturale.

Jasper van den Bosch
la source
8

Je pense que la chose la plus importante à garder à l'esprit est: le nom est-il suffisamment descriptif? Pouvez-vous dire en regardant le nom de ce que la classe est censée faire? L'utilisation de mots tels que "Manager", "Service" ou "Handler" dans les noms de classe peut être considérée comme trop générique, mais comme beaucoup de programmeurs les utilisent, cela permet également de comprendre à quoi sert la classe.

J'ai moi-même beaucoup utilisé le motif de la façade (du moins, je pense que c'est ainsi qu'on l'appelle). Je pourrais avoir une Userclasse qui décrit un seul utilisateur et une Usersclasse qui garde une trace de ma "collection d'utilisateurs". Je n'appelle pas la classe un UserManagerparce que je n'aime pas les gestionnaires dans la vie réelle et je ne veux pas me souvenir d'eux :) Le simple fait d'utiliser le pluriel m'aide à comprendre ce que fait la classe.

Droozle
la source
J'aime aussi beaucoup cette approche car elle atténue l'idée d'une gestion descendante des objets. Un groupe d'utilisateurs est plus susceptible d'impliquer que le travail est effectué entre les utilisateurs plutôt que depuis le UserManager. En outre, avoir un utilisateur possédant une référence aux utilisateurs ne semble pas aussi étrange que posséder UserManager. C'est plus ouvert à la pensée relative, plutôt que strictement OOP.
Seph Reed
Le problème avec cette approche est qu'il devient vraiment difficile de rechercher votre code Users, surtout si vous passez autour de l'objet gestionnaire. this.users = new Users()Mais alors invariablement ailleurs dans votre code usersfera référence à un tableau de Users.
Snowman
Comme vous le dites, les utilisateurs impliquent en effet une "collection d'utilisateurs" - une collection d'entités avec état. Mais SRP signifierait que vous ne voudriez pas regrouper la gestion des utilisateurs (fonctionnalité et logique métier) avec les données utilisateur (état). Ne dites pas que vous vous trompez, juste que UserManager est approprié si la classe est responsable de la gestion des utilisateurs et pas seulement du stockage de leur état et de leur CRUD de base.
Richard Moore
5

Spécifique à C #, j'ai trouvé que «Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries» contenait beaucoup de bonnes informations sur la logique du nommage.

Pour ce qui est de trouver ces mots plus spécifiques, j'utilise souvent un thésaurus et je passe par des mots apparentés pour essayer d'en trouver un bon. J'essaie de ne pas passer trop de temps avec cela, alors que je progresse dans le développement, je trouve de meilleurs noms, ou je me rends parfois compte que cela SuchAndSuchManagerdevrait vraiment être divisé en plusieurs classes, puis le nom de cette classe obsolète devient un non-problème .

AaronLS
la source
3

Je crois que la chose essentielle ici est d'être cohérent dans le domaine de la visibilité de votre code, c'est-à-dire aussi longtemps que tout le monde qui a besoin de regarder / travailler sur votre code comprend votre convention de dénomination, alors ça devrait aller, même si vous décidez de les appeler «CompanyThingamabob» et «UserDoohickey». Le premier arrêt, si vous travaillez pour une entreprise, est de voir s'il existe une convention d'entreprise pour la dénomination. S'il n'y en a pas ou si vous ne travaillez pas pour une entreprise, créez les vôtres en utilisant des termes qui ont du sens pour vous, faites-le circuler auprès de quelques collègues / amis de confiance qui codent au moins de manière décontractée, et intégrez les commentaires qui ont du sens.

Appliquer la convention de quelqu'un d'autre, même lorsqu'elle est largement acceptée, si elle ne saute pas de la page chez vous est un peu une erreur dans mon livre. Avant tout, je dois comprendre mon code sans référence à d'autres documents, mais en même temps, il doit être suffisamment générique pour qu'il ne soit pas incompréhensible pour quelqu'un d'autre dans le même domaine dans la même industrie.

Lazare
la source
1
Néanmoins, une convention cohérente, quoique légèrement non intuitive, est préférable au simple démarrage de votre propre convention. Les personnes travaillant sur un projet apprendront très rapidement toute convention cohérente et oublieront bientôt que la fonctionnalité n'est pas tout à fait ce à quoi on pourrait s'attendre à première vue.
M. Boy
@John, c'est exactement ce que j'ai dit. La convention doit être acceptée par le groupe et si vous travaillez dans une entreprise, vérifiez s'il existe une convention d'entreprise. Pour l'entreprise, je pense à n'importe quel groupe, que ce soit une équipe de projet open source ou une collection lâche de programmeurs. Si tout le monde prenait ce qui était disponible qui correspondait presque à leurs besoins, je pense que nous manquerions cruellement d'innovation.
Lazarus
2

Je considérerais les modèles que vous utilisez pour votre système, les conventions de dénomination / catalogage / regroupement des classes de tendances à définir par le modèle utilisé. Personnellement, je m'en tiens à ces conventions de dénomination car elles sont le moyen le plus probable pour une autre personne de récupérer mon code et de l'exécuter.

Par exemple, UserRecordsClerk pourrait être mieux expliqué comme étendant une interface RecordsClerk générique qu'UserRecordsClerk et CompanyRecordsClerk implémentent puis spécialisent, ce qui signifie que l'on peut regarder les méthodes dans l'interface pour voir à quoi servent généralement ses sous-classes.

Voir un livre tel que Design Patterns pour plus d'informations, c'est un excellent livre et pourrait vous aider à clarifier où vous visez avec votre code - si vous ne l'utilisez pas déjà! ; o)

Je pense que tant que votre modèle est bien choisi et utilisé autant qu'il est approprié, des noms de classe simples et non inventifs devraient suffire!

Caroline
la source
J'ai commenté cela sur la réponse de Brian Agnew. Je ne pense pas que les noms de modèle fassent de bons noms de classe uniquement dans certains cas (Factory, Strategy) mais pas dans d'autres (Singleton). Je veux que les noms reflètent le travail de la classe et non la façon dont je l'ai implémenté.
froh42