Nombrar clases: ¿cómo evitar llamar a todo un "<WhatEver> Manager"? [cerrado]

1188

Hace mucho tiempo leí un artículo (creo que es una entrada de blog) que me puso en la pista "correcta" en nombrar objetos: sea muy escrupuloso al nombrar cosas en su programa.

Por ejemplo, si mi solicitud fue (como una aplicación de negocios típico) el manejo de usuarios, empresas y direcciones que tendría un User, una Company, y una Addressclase de dominio - y probablemente en algún lugar de una UserManager, una CompanyManagery un AddressManagersurgiría que se encarga de esas cosas.

Así se puede saber lo que aquellos UserManager, CompanyManagery AddressManagerhacer? No, porque Administrador es un término muy genérico que se adapta a todo lo que puede hacer con sus objetos de dominio.

El artículo que leí recomienda usar nombres muy específicos. Si se tratara de una aplicación C ++ y el UserManagertrabajo de la persona fuera asignar y liberar a los usuarios del montón, no gestionaría a los usuarios sino que protegería su nacimiento y muerte. Hmm, tal vez podríamos llamar a esto a UserShepherd.

O tal vez el UserManagertrabajo de este es examinar los datos de cada objeto de usuario y firmar los datos criptográficamente. Entonces tendríamos un UserRecordsClerk.

Ahora que esta idea me quedó grabada, trato de aplicarla. Y encuentra esta idea simple increíblemente difícil.

Puedo describir lo que hacen las clases y (siempre y cuando no me meta en la codificación rápida y sucia) las clases que escribo hacen exactamente una cosa. Lo que echo de menos de esa descripción a los nombres es una especie de catálogo de nombres, un vocabulario que asigna los conceptos a los nombres.

En última instancia, me gustaría tener algo como un catálogo de patrones en mi mente (con frecuencia, los patrones de diseño proporcionan fácilmente los nombres de los objetos, por ejemplo, una fábrica )

  • Fábrica: crea otros objetos (nombres tomados del patrón de diseño)
  • Pastor: un pastor maneja la vida útil de los objetos, su creación y apagado
  • Sincronizador: copia datos entre dos o más objetos (o jerarquías de objetos)
  • Niñera: ayuda a los objetos a alcanzar el estado "utilizable" después de la creación, por ejemplo, mediante el cableado a otros objetos

  • etcétera etcétera.

Entonces, ¿cómo manejas ese problema? ¿Tiene un vocabulario fijo, inventa nuevos nombres sobre la marcha o considera nombrar cosas no tan importantes o incorrectas?

PD: También me interesan los enlaces a artículos y blogs que discuten el tema. Para empezar, aquí está el artículo original que me hizo pensar en ello: nombrar clases de Java sin un "administrador"


Actualización: resumen de respuestas

Aquí hay un pequeño resumen de lo que aprendí de esta pregunta mientras tanto.

  • Intenta no crear nuevas metáforas (niñera)
  • Echa un vistazo a lo que hacen otros frameworks

Más artículos / libros sobre este tema:

Y una lista actual de prefijos / sufijos de nombre que recopilé (¡subjetivamente!) De las respuestas:

  • Coordinador
  • Constructor
  • Escritor
  • Lector
  • Manipulador
  • Envase
  • Protocolo
  • Objetivo
  • Convertidor
  • Controlador
  • Ver
  • Fábrica
  • Entidad
  • Cubeta

Y un buen consejo para el camino:

No te pongas parálisis de nombres. Sí, los nombres son muy importantes, pero no son lo suficientemente importantes como para perder grandes cantidades de tiempo. Si no puede pensar en un buen nombre en 10 minutos, continúe.

froh42
fuente
11
Pertenece a la wiki de la comunidad porque no hay una "mejor" respuesta. Es una discusión.
DOK
13
Eso es contrario a la intuición. ¿No deberían llamarlo un foro? Creo que un wiki sería para una colección de hechos, no opiniones.
AaronLS
78
Gracias por mantener esto actualizado, ¡pero ese último consejo es un consejo terrible! Si no puede pensar en un buen nombre en 10 minutos, probablemente haya algo mal con su clase. (Con las advertencias estándar: 1) perfecto es el enemigo del bien, 2) El envío es una característica, solo recuerda que estás incurriendo en una deuda técnica.)
Jeff Sternal
11
Si no puede pensar en un buen nombre en 10 minutos, pida ayuda a su colega. No te rindas.
99
Si no puede pensar en un buen nombre en 10 minutos, intente explicárselo a sus colegas; que podrían pensar en un nombre bueno (user338195), pero tratando de explicar que probablemente le ayudará a descubrir lo que está mal con él ( Jeff ).
WillC

Respuestas:

204

Hice una pregunta similar , pero siempre que sea posible trato de copiar los nombres que ya están en el marco .NET , y busco ideas en los marcos Java y Android .

Parece Helper, Managery Utilson los sustantivos inevitables que adjuntas para coordinar clases que no contienen estado y generalmente son de procedimiento y estáticos. Una alternativa es Coordinator.

Se podía conseguir prosey particularmente púrpura con los nombres e ir a por cosas como Minder, Overseer, Supervisor, Administrator, y Master, pero, como dije, prefiero mantenerlo como los nombres marco que está acostumbrado.


Algunos otros sufijos comunes (si ese es el término correcto) que también encuentra en .NET Framework son:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container
Chris S
fuente
44
Me gustan mucho estos No caen en la trampa de metáforas malas o desconocidas porque ya están en uso por .NET Framework. Puede ser interesante mirar otras bibliotecas (Java) también para obtener más información sobre lo que se usa comúnmente.
froh42
Me gustaría sugerir Conductor, como el director de una orquesta musical. Seguramente es un papel importante, dependiendo de la naturaleza de las colaboraciones que necesita "realizar" (otros objetos son actores muy especializados que deben responder al comando centralizado y no preocuparse demasiado por cualquier otro colaborador).
heltonbiker
1
No creo que la solución para las clases -er sea crear un nombre diferente. Como he leído en muchas otras publicaciones y estoy tratando de aprender la respuesta, es que necesitas cambiar la arquitectura, no solo el nombre utilizado.
Michael Ozeryansky el
115

Puede echar un vistazo a source-code-wordle.de , he analizado allí los sufijos más utilizados de los nombres de clase del marco .NET y algunas otras bibliotecas.

Los 20 principales son:

  • atributo
  • tipo
  • ayudante
  • colección
  • convertidor
  • manipulador
  • informacion
  • proveedor
  • excepción
  • Servicio
  • elemento
  • gerente
  • nodo
  • opción
  • fábrica
  • contexto
  • articulo
  • diseñador
  • base
  • editor
Markus Meyer
fuente
147
Hace mucho tiempo, en una compañía en particular, conocía a un ingeniero tan harto de la absurda y creciente cantidad de reglas de sufijos que asolaban la compañía con la que definitivamente terminaba cada clase Thingy.
8
Esta lista de nombres en sí misma no es tan útil sin el contexto del cual se debe aplicar el sufijo.
Fred
65

Estoy a favor de los buenos nombres, y a menudo escribo sobre la importancia de tener mucho cuidado al elegir nombres para las cosas. Por esta misma razón, desconfío de las metáforas al nombrar cosas. En la pregunta original, "fábrica" ​​y "sincronizador" parecen buenos nombres para lo que parecen significar. Sin embargo, "pastor" y "niñera" no lo son, porque se basan en metáforas . Una clase en su código no puede ser literalmente una niñera; lo llamas niñera porque se ocupa de otras cosas de manera muy parecida a como una niñera de la vida real cuida bebés o niños. Eso está bien en el discurso informal, pero no está bien (en mi opinión) para nombrar clases en código que deberán ser mantenidas por quién sabe quién quién sabe cuándo.

¿Por qué? Porque las metáforas dependen de la cultura y, a menudo, también dependen del individuo. Para usted, nombrar a una "niñera" de la clase puede ser muy claro, pero tal vez no sea tan claro para otra persona. No debemos confiar en eso, a menos que esté escribiendo un código que sea solo para uso personal.

En cualquier caso, la convención puede hacer o deshacer una metáfora. El uso de la "fábrica" ​​en sí se basa en una metáfora, pero que ha existido durante bastante tiempo y actualmente es bastante conocida en el mundo de la programación, por lo que diría que es segura de usar. Sin embargo, "niñera" y "pastor" son inaceptables.

CesarGon
fuente
10
Este argumento realmente se rompe en que, obviamente, la Fábrica misma es una metáfora. A menudo, las metáforas realmente aclararán en qué puede ser bueno un objeto, mientras que ser vago o genérico automáticamente asegura que la única forma de descubrir qué hace el código es leerlo completamente. El peor de los casos.
Kzqai
1
+1 para evitar nombres 'lindos'. Creo que es genial ser tan directo con el lenguaje como puedas ser. (Por supuesto, no siempre es fácil ser directo, sucinto, preciso y sin ambigüedades, todo al mismo tiempo ...)
andrewf
1
Una elección inventiva de verbo + "er" generalmente será más clara para clases concretas que una analogía colorida. Las nuevas abstracciones, por otro lado, cosas que son un concepto nuevo, un nuevo "tipo de cosa" en lugar de una nueva "cosa", a menudo funcionan bien como metáforas ("beans" de Java, "lentes" de Haskell, GUI "Windows", "promesas" de muchos idiomas). Sin embargo, la mayoría de las bases de código no tendrán inventos genuinos como ese.
Malnormalulo
51

Podríamos prescindir de cualquiera xxxFactory, xxxManagero xxxRepositoryclases si modelamos el mundo real correctamente:

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

;-)

revs herzmeister
fuente
11
¿Cómo llegarías a universos paralelos y dimensiones alternativas?
tster
23
Eso es fácil: Omniverse.Instance.Dimensions ["Ours"]. Universes ["Ours"]. Galaxies ... ... okay okay admito que esto requeriría una recompilación. ;-)
herzmeister
73
Actualización: esto se agregó en .NET 4.0:; Universe.Instance.ToParallel())
Connell
2
¡Pero rompe la ley de Deméter!
Jonas G. Drange
13
Esos son objetos y miembros, no nombres de clase
Harry Berry
39

Suena como una pendiente resbaladiza a algo que se publicaría en thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages", etc.

Supongo que es correcto que una clase de Administrador monolítico no sea un buen diseño, pero usar 'Administrador' no es malo. En lugar de UserManager, podríamos dividirlo en UserAccountManager, UserProfileManager, UserSecurityManager, etc.

'Gerente' es una buena palabra porque muestra claramente que una clase no representa una 'cosa' del mundo real. 'AccountClerk': ¿cómo se supone que debo decir si esa es una clase que administra los datos del usuario o representa a alguien que es un empleado de cuentas para su trabajo?

Señor chico
fuente
8
¿Qué pasa con UserAccounter, UserProfiler y UserSecurer? Si se deshace de Manager, se ve obligado a encontrar una definición específica, lo que creo que es algo bueno.
Didier A.
10
¿Qué pasa con UserAccount, UserProfile, UserSecurity oO?
Clima
3
Lo llamaría "MortageOwnersManager"
volter9
A veces el dominio tiene nombres específicos. Como "MortageHolder" que puede ser mejor que "MortageOwner"
borjab
24

Cuando me encuentro pensando en usar Managero Helperen un nombre de clase, lo considero un olor a código que significa que todavía no he encontrado la abstracción correcta y / o estoy violando el principio de responsabilidad única , por lo que refactorizo ​​y pongo más esfuerzo en el diseño a menudo hace que nombrar sea mucho más fácil.

Pero incluso las clases bien diseñadas no (siempre) se nombran a sí mismas, y sus elecciones dependen en parte de si está creando clases de modelo de negocio o clases de infraestructura técnica.

Las clases de modelo de negocio pueden ser difíciles, porque son diferentes para cada dominio. Hay algunos términos que uso mucho, como Policypara las clases de estrategia dentro de un dominio (p. Ej. LateRentalPolicy), Pero estos generalmente provienen de tratar de crear un " lenguaje ubicuo " que pueda compartir con los usuarios de negocios, diseñando y nombrando clases para que modelen -Ideas, objetos, acciones y eventos mundiales.

Las clases de infraestructura técnica son un poco más fáciles, porque describen dominios que conocemos realmente bien. Prefiero incorporar nombres de patrones de diseño en los nombres de clase, como InsertUserCommand, CustomerRepository,o SapAdapter.entiendo la preocupación por comunicar la implementación en lugar de la intención, pero los patrones de diseño combinan estos dos aspectos del diseño de clase, al menos cuando se trata de infraestructura, donde desea El diseño de implementación será transparente incluso mientras oculta los detalles.

Jeff Sternal
fuente
1
Me gusta mucho la idea de usar el Policysufijo para las clases que contienen la lógica de negocio
jtate
+1 por mencionar el olor del código asociado con nombres como "Administrador" y "Ayudante". Me parece que si no tengo nombres claros para las cosas, generalmente se debe al menos en parte a cierta confusión en mi comprensión del dominio, ya sea comercial o técnico. De manera casi equivalente, podría significar que estoy interrumpiendo las clases de manera reactiva porque "se hicieron demasiado grandes", lo que para mí también es una señal de modelado inadecuado. Esta debería ser la respuesta más votada.
nclark
10

Ser auténtico con los patrones definidos por (digamos) el libro GOF , y nombrar objetos después de estos me ayuda mucho en nombrar clases, organizarlas y comunicar la intención. La mayoría de las personas entenderán esta nomenclatura (o al menos una parte importante de ella).

Brian Agnew
fuente
Fowler es una buena referencia para mí, pero el GOF es una gran recomendación.
Lazarus
Perdona mi ignorancia. ¿A qué libro de Fowler te refieres?
Brian Agnew
19
Hmm, a veces esto funciona (por ejemplo, como una Fábrica o una Estrategia), pero en otras ocasiones siento que esto comunica la forma de implementación (¡usé un patrón!) Más que la intención y el trabajo de la clase. Por ejemplo, lo más importante de un Singleton es lo que representa, y no es que sea un Singleton. Por lo tanto, los nombres estrictos después de los patrones utilizados se sienten como nombres estrictos después de los tipos utilizados. Por ejemplo, la notación húngara como aplicada
incorrectamente
1
Para las clases de infraestructura técnica, generalmente es deseable hacer que la implementación sea transparente, y la mayoría de los nombres de patrones de diseño canónico comunican tanto la implementación como la intención. Sin embargo, las clases de modelo de dominio son otro asunto.
Jeff Sternal
10

Si no puedo encontrar un nombre más concreto para mi clase que XyzManager, este sería un punto para que reconsidere si esta es realmente una funcionalidad que pertenece a una clase, es decir, un "olor a código" arquitectónico.

Jasper van den Bosch
fuente
8

Creo que lo más importante a tener en cuenta es: ¿es el nombre lo suficientemente descriptivo? ¿Puedes decir mirando el nombre lo que se supone que debe hacer la Clase? El uso de palabras como "Administrador", "Servicio" o "Manejador" en los nombres de sus clases puede considerarse demasiado genérico, pero dado que muchos programadores los usan, también ayuda a comprender para qué sirve la clase.

Yo mismo he estado usando mucho el patrón de fachada (al menos, creo que así se llama). Podría tener una Userclase que describa a un solo usuario, y una Usersclase que haga un seguimiento de mi "colección de usuarios". No llamo a la clase un UserManagerporque no me gustan los gerentes en la vida real y no quiero que me lo recuerden :) Simplemente usar el formulario plural me ayuda a entender lo que hace la clase.

Droozle
fuente
También me gusta mucho este enfoque porque alivia la idea de la gestión de objetos de arriba hacia abajo. Es más probable que un grupo de usuarios implique que el trabajo se realiza entre usuarios en lugar de hacerlo desde el Administrador de usuarios hacia abajo. Además, tener un usuario que tenga una referencia a los usuarios no se siente tan extraño como ser propietario de UserManager. Está más abierto al pensamiento relativo, en lugar de estrictamente POO.
Seph Reed
El problema con este enfoque es que es muy difícil buscar su código Users, especialmente si pasa el objeto del administrador. this.users = new Users()Pero, invariablemente, en algún otro lugar de su código usersse referirá a una matriz de Users.
Muñeco de nieve
Como usted dice, los usuarios realmente implican una "colección de usuarios", una colección de entidades con estado. Pero SRP significaría que no querría agrupar la gestión de usuarios (funcionalidad y lógica empresarial) con los datos del usuario (estado). No digo que esté equivocado, solo que UserManager es apropiado si la clase es responsable de administrar usuarios y no solo de almacenar su estado y CRUD básico.
Richard Moore
5

Específico para C #, encontré que las "Pautas de diseño de marcos: convenciones, modismos y patrones para bibliotecas .NET reutilizables" tienen mucha buena información sobre la lógica de los nombres.

Sin embargo, en cuanto a encontrar esas palabras más específicas, a menudo uso un diccionario de sinónimos y salto a través de palabras relacionadas para tratar de encontrar una buena. Sin embargo, trato de no pasar mucho tiempo con eso, a medida que avanzo en el desarrollo encuentro mejores nombres, o a veces me doy cuenta de que SuchAndSuchManagerrealmente debería dividirse en varias clases, y luego el nombre de esa clase obsoleta se convierte en un problema. .

AaronLS
fuente
3

Creo que lo importante aquí es ser coherente dentro de la esfera de la visibilidad de su código, es decir, siempre y cuando todos los que necesiten ver / trabajar en su código comprendan su convención de nomenclatura, eso debería estar bien, incluso si decide llamarlos. 'CompanyThingamabob' y 'UserDoohickey'. La primera parada, si trabaja para una empresa, es ver si hay una convención de empresa para nombrar. Si no existe o no trabaja para una empresa, cree los suyos utilizando términos que tengan sentido para usted, páselos a algunos colegas / amigos confiables que al menos codifiquen casualmente e incorpore cualquier comentario que tenga sentido.

Aplicar la convención de otra persona, incluso cuando es ampliamente aceptado, si no se salta de la página, es un error en mi libro. En primer lugar, necesito comprender mi código sin hacer referencia a otra documentación, pero al mismo tiempo debe ser lo suficientemente genérico como para que no sea incomprensible para otra persona en el mismo campo en la misma industria.

Lázaro
fuente
1
Aún así, una convención consistente, aunque poco intuitiva, es mejor que simplemente comenzar su propia convención. Las personas que trabajan en un proyecto aprenderán cualquier convención consistente muy rápido y pronto olvidarán que la funcionalidad no es lo que cabría esperar a primera vista.
Sr. Boy
@ John, eso es exactamente lo que dije. La convención debe ser aceptada por el grupo y si está trabajando en una empresa, vea si hay una convención de la empresa. Para la compañía, estoy pensando en cualquier grupo, ya sea un equipo de proyecto de código abierto o una colección suelta de programadores. Si todos tomaran lo que estaba disponible y que casi se ajustara a sus requisitos, creo que nos faltaría mucha innovación.
Lázaro
2

Consideraría los patrones que está utilizando para su sistema, las convenciones de nomenclatura / catalogación / agrupación de clases de clases tienden a definirse por el patrón utilizado. Personalmente, me adhiero a estas convenciones de nombres, ya que son la forma más probable para que otra persona pueda recoger mi código y ejecutarlo.

Por ejemplo, UserRecordsClerk podría explicarse mejor como extender una interfaz genérica RecordsClerk que tanto UserRecordsClerk como CompanyRecordsClerk implementan y luego se especializan, lo que significa que uno puede ver los métodos en la interfaz para ver para qué sirven / son en general sus subclases.

Vea un libro como Patrones de diseño para obtener información, es un libro excelente y podría ayudarlo a aclarar dónde está tratando de estar con su código, ¡si aún no lo está usando! ; o)

Creo que siempre y cuando su patrón esté bien elegido y se use en la medida adecuada, ¡bastarán con nombres de clase bastante simples y poco innovadores!

carolino
fuente
He comentado sobre eso en la respuesta de Brian Agnew. No creo que los nombres de patrones sean buenos nombres de clase solo en algunos casos (Fábrica, Estrategia) pero no en otros (Singleton). Quiero que los nombres reflejen el trabajo de la clase, no la forma en que lo implementé.
froh42