Una pregunta incómoda y abierta, pero es un problema con el que siempre me encuentro:
El software que es fácil de mantener y trabajar es un software bien diseñado. Intentar hacer un diseño intuitivo significa nombrar sus componentes de tal manera que el próximo desarrollador pueda inferir la función del componente. Es por eso que no nombramos nuestras clases "Tipo1", "Tipo2", etc.
Cuando modela un concepto del mundo real (por ejemplo, cliente), esto generalmente es tan simple como nombrar su tipo después del modelo del mundo real que se está modelando. Pero cuando construye cosas abstractas, que están más orientadas al sistema, es muy fácil quedarse sin nombres que sean fáciles de leer y de digerir.
Empeora (para mí) cuando intento nombrar familias de tipos, con un tipo base o interfaz que describe lo que los componentes tienen que hacer, pero no cómo funcionan. Naturalmente, esto lleva a que cada tipo derivado intente describir el sabor de la implementación (por ejemplo, IDataConnection
y SqlConnection
en .NET Framework), pero ¿cómo expresa algo complicado como "funciona por reflexión y busca un conjunto específico de atributos"?
Luego, cuando finalmente has elegido un nombre para el tipo que crees que describe lo que está tratando de hacer, tu colega pregunta "¿ Qué hace esto DomainSecurityMetadataProvider
realmente ? "
¿Existen buenas técnicas para elegir un nombre bien intencionado para un componente, o cómo construir una familia de componentes sin obtener nombres confusos?
¿Hay alguna prueba simple que pueda aplicar a un nombre para tener una mejor idea de si el nombre es "bueno" y debería ser más intuitivo para los demás?
Respuestas:
Para nombrar, hay seis técnicas que fueron probadas para mí:
PD. En caso de que su API sea pública, lo anterior se aplica antes de eso, porque, ya sabes,
fuente
Mi prueba base es si puedes describir la función de la variable usando solo palabras de la variable:
Sin embargo, hay matices que varían de persona a persona:
Entonces, mi prueba extendida es escribir la variable en un tablero / wiki / chat, y hacer que la gente adivine lo que significa.
fuente
Realmente no.
Un consejo, sin embargo, es evitar la "voz pasiva".
"DomainSecurityMetadataProvider" es pasivo. No hay verbo, todos son sustantivos y sustantivos utilizados como adjetivos.
"ProvideMetadataForDomainSecurity" está más activo. Hay un verbo
La programación orientada a objetos es (realmente) sustantivo-verbo. Sustantivo == objeto. Verbo == método. Entonces un nombre de clase es generalmente muy "sustantivo". Romper este hábito y comenzar a insertar verbos es difícil.
Sí. Definiste una excelente prueba en tu pregunta. Pregunta a otras personas.
En los viejos tiempos lo llamamos un "tutorial de diseño". Fue un gran negocio sudoroso en una metodología de cascada. Hoy en día, con los métodos ágiles, debería ser una colaboración ordinaria entre el autor y los usuarios de una clase. No (y no debería) tomar mucho tiempo. Discutir el diseño (y los nombres) antes de escribir las pruebas (y el código) reducirá el factor de asombro y puede evitar los WTF.
fuente
ProvideMetadataForDomainSecurity
ser un nombre de tipo pobre. Los nombres de los métodos suelen ser mucho más fáciles de nombrar precisamente porque soy libre de usar verbos. La restricción del idioma es el quid de la cuestión.Usando un tesauro
Muy a menudo me referiré a un diccionario de sinónimos cuando haga un nuevo desarrollo para encontrar palabras apropiadas para describir mis clases y métodos.
Clases que contienen principalmente lógica de operación
Tiendo a nombrar clases que proporcionan principalmente métodos de operación en una estructura de sustantivo-verbo como "EntityProvider", "EntityLocator", etc.
Estas clases generalmente no contienen mucho estado.
Clases que contienen estado
Las pantallas de la interfaz de usuario y las entidades de datos generalmente tienen estado, por lo que simplemente nombro estas clases con un patrón de nombre o adjetivo-nombre.
Ejemplos: persona, empleado, empleado actual, antiguo empleado
Clases de utilidad
Las clases que solo contienen métodos estáticos generalmente se consideran clases de "utilidad", por lo que siempre las llamo con el sufijo "Utilidad".
Ejemplos: NetworkUtilities, FileUtilities
Pruebas
No tengo buenas pruebas para decidir si algo está mal nombrado, pero sugeriría intentar usar un solo nombre y / o un solo verbo en el nombre, luego pensar si ese nombre / verbo describe con precisión lo que usted ' renombrando.
Si cree que hay más en la clase / método que no está capturado por el nombre, entonces esa clase / método podría necesitar una refactorización.
Alan Green y Jeff Attwood han escrito sobre los males de nombrar clases con el sufijo "Manager". Argumentan que el término "Gerente" se usa en exceso y es demasiado vago para transmitir algo significativo. Tengo que estar de acuerdo.
El artículo de Jeff también proporciona una lista de pautas sugeridas del Código completo de Steve McConnell.
variables
Recientemente he estado experimentando con nombres de variables / parámetros descriptivos más largos que incorporan preposiciones, como "Of", "By", "For", etc. A continuación se muestran algunos ejemplos:
Me parece que esto funciona bien con la función intellisense de Visual Studio que hace que sea fácil escribir estos nombres largos. También encuentro que hay menos duplicación de prefijos de nombres de variables (por ejemplo, personID, personFirstName, personLastName vs.idOfPerson, firstNameOfPerson, lastNameOfPerson), proporcionando un mejor "hash" que hace que intellisense sea aún más útil.
fuente
List
, matrizIEnumerable
oConcurrentQueue
. Es un conjunto de ID que necesito enumerar, y el detalle de implementación de cómo se almacenan es un equipaje mental innecesario. Aunque generalmente estoy de acuerdo en que si un nombre más largo es considerablemente más descriptivo, debería preferirse a un nombre más corto y menos claro.¿Qué tipo de nombre esperas para una clase compleja y específica de dominio? Esto es casi tan bueno como va a ser sin hacer que el nombre de su clase sea una oración (lo que hará que todos piensen que ha dado demasiada responsabilidad a una sola clase)
Consideraría eliminar al proveedor del nombre. Si menciona específicamente los metadatos, todos ya saben que está utilizando la reflexión. Podría hacerlo una palabra más concisa (o posiblemente cambiar a otra palabra, es más un consumidor que un proveedor por lo que ha escrito)
fuente
ISecurityMetadataProvider
interfaz, que existe un punto inyectable en la infraestructura de seguridad, para proporcionar información al subsistema. Nombrar es difícil.DomainSecurityMetadataProvider
ser un proveedor deDomainSecurityMetadata
objetos, dondeDomainSecurityMetadata
están los metadatos en sí. Nombre claro y entendible. ¡Ni siquiera necesito saber quéDomainSecurityMetadata
es! Es solo un objeto que proporciona este proveedor. Solo eliminar unProvider
sufijo no mejora la legibilidad, sino todo lo contrario: reduzca. Sin este sufijo, pensaría que son solo algunos metadatos (objeto contenedor para algunos metadatos), pero no un objeto para obtener metadatos de (un proveedor).Usa metáforas para describir partes del sistema. No solo te hará descubrir nuevas analogías, sino que te ayudará a nombrar más fácilmente.
(Soy consciente de que este no es un ejemplo sólido, pero de todos modos) Por ejemplo, puede llamar a una variable o un tipo como
mailbox
, que sirve como una cola para los mensajes recibidos para una clase.fuente
Una cosa en la que sería muy firme es que NUNCA se debe permitir que sean incorrectos. El mejor ejemplo, durante algunas refactorizaciones, cambió mucho código y algunas variables comenzaron a referirse a algo diferente a lo que sugerían sus nombres.
Muy pronto, un programador estaba pasando años y utilizando algunas llamadas de bases de datos muy costosas tratando de obtener ciertos datos que ya se habían extraído y almacenado. Cambié el nombre de todo y de repente pudimos eliminar un montón de lógica demasiado complicada y con errores.
fuente
Con suerte, los casos en los que hay que pensar tanto sobre los nombres son raros. Cuando surjan esos casos, solo escriba un párrafo que explique lo que hace la clase. Contrariamente a los comentarios en función o comentarios a nivel de función, el propósito principal de una clase rara vez cambia, por lo que el riesgo de que los comentarios se desactualicen es relativamente pequeño. Así que tiene el lujo de escribir un par de párrafos o incluso dibujar ASCII para explicar lo que hace la clase.
fuente