¿Alguien más considera que las clases y métodos de denominación son una de las partes más difíciles de la programación? [cerrado]

275

Así que estoy trabajando en esta clase que se supone que solicita documentación de ayuda de un proveedor a través de un servicio web. Trato de nombrarlo DocumentRetriever, VendorDocRequester, DocGetter, pero simplemente no suenan bien. Terminé navegando por dictionary.com durante media hora tratando de encontrar una palabra adecuada.

Comenzar a programar con malos nombres es como tener un mal día de cabello por la mañana, el resto del día va cuesta abajo desde allí. ¿Sienteme?

Haoest
fuente
2
¿Por qué querrías una clase, cuando claramente solo necesitas una función? Asegúrese de revisar steve-yegge.blogspot.com/2006/03/… para ver el problema del verbo como nombre de clase.
user51568
O bien, avance y refactorice cuando finalmente sepa cómo debe llamarse.
Esteban Araya
16
¿Qué estás nombrando ? : métodos : usa verbos , como get, set, save, etc. clases y variables : usa sustantivos , como documento, usuario, contexto, etc. interfaces : usa adjetivos , como imprimible, clonable, iterable, etc. Después de leer este hilo, me gusta la sugerencia de Spolsky para clases y variables (usa sustantivos) y la sugerencia de TravisO para métodos (usa verbos). Tampoco haga objetos que terminen con 'er' .
Daniel Gasull
55
"Hay dos problemas difíciles en informática: invalidación de caché, convenciones de nombres y desbordamiento silencioso".
Karakuri
66
@karakuri La versión que escuché es "hay 2 problemas difíciles en informática: nombrar y compensar por 1 error".
Haoest

Respuestas:

121

Lo que está haciendo ahora está bien, y le recomiendo que siga con su sintaxis actual, siendo:

contexto + verbo + cómo

Uso este método para nombrar funciones / métodos, procesos almacenados SQL, etc. Al mantener esta sintaxis, mantendrá sus paneles Intellisense / Code mucho más limpios. Entonces desea EmployeeGetByID () EmployeeAdd (), EmployeeDeleteByID (). Cuando usa una sintaxis gramaticalmente más correcta, como GetEmployee (), AddEmployee (), verá que esto se vuelve realmente complicado si tiene múltiples Gets en la misma clase, ya que las cosas no relacionadas se agruparán.

Al igual que nombrar archivos con fechas, quiere decir 2009-01-07.log no 1-7-2009.log porque después de tener un montón de ellos, el orden se vuelve totalmente inútil.

TravisO
fuente
28
Prefiero tener un contexto inferido del nombre del tipo al nombrar los métodos ... class EmployeeRepository {void Add (Employee employee); void Get (int id); nulo GetAll (); nulo GetAll (filtro Action <FilterCriteria>); } ¿Qué piensas?
Vyas Bharghava
55
También ayuda si tienes una lista estándar de verbos "house". Por lo tanto, siempre es Obtener y no Cargar / Leer / Recuperar / Seleccionar / Buscar ... etc.
Cuenta muerta el
2
Richard, tienes razón en los escenarios de OOP, mi respuesta se retiró un poco y fue más una sugerencia de codificación general. Supongo que técnicamente se aplica más a los idiomas que no son OOP. Employee.Add () y Employee.GetByID () sería el mejor uso en OOP.
TravisO
66
Me gusta el efecto Intellisense de su sugerencia, pero prefiero un enfoque un poco más alfabetizado. Por lo tanto, preferiría Employee.SetSupervisor () sobre Employee.SupervisorSet () porque lee (más como inglés natural.
Matthew Maravillas,
12
Pero @TravisO, esto no suena bien en inglés. No obtienes empleados, obtienes un empleado. ¿Qué sucede si tiene acciones más complejas que involucran adjetivos, como InvalidateObsoleteQueries? QueriesInvalidateObsoleteEs difícil de leer y no tiene sentido. Además, en C #, especialmente con Resharper, el orden alfabético es irrelevante. Si comienza a escribir "EMP", ReSharper le dará GetEmployee, SetEmployeey aun PopulateInactiveEmployeesList.
Ilya Kogan
54

Una lección que aprendí es que si no puedes encontrar el nombre de una clase, casi siempre hay algo mal con esa clase:

  • no lo necesitas
  • hace demasiado
rev. Toon Krijthe
fuente
13
O hace muy poco.
user51568
44
Gracias, esto fue realmente relevante para mí.
Haoest
52

Una buena convención de nomenclatura debería minimizar la cantidad de nombres posibles que puede usar para cualquier variable, clase, método o función dados. Si solo hay un nombre posible, nunca tendrá problemas para recordarlo.

Para las funciones y para las clases singleton, analizo la función para ver si su función básica es transformar un tipo de cosa en otro tipo de cosas. Estoy usando ese término muy libremente, pero descubrirás que una ENORME cantidad de funciones que escribes esencialmente toman algo en una forma y producen algo en otra forma.

En su caso, parece que su clase transforma una URL en un documento. Es un poco extraño pensarlo de esa manera, pero perfectamente correcto, y cuando comiences a buscar este patrón, lo verás en todas partes.

Cuando encuentro este patrón, siempre nombro la función x Fromy .

Como su función transforma una URL en un documento, lo nombraría

DocumentFromUrl

Este patrón es notablemente común. Por ejemplo:

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

También podría usarlo UrlToDocumentsi se siente más cómodo con ese orden. Si dices x Fromy o y Tox es probablemente una cuestión de gustos, pero prefiero el Fromorden porque de esa manera el comienzo del nombre de la función ya te dice qué tipo devuelve.

Elija una convención y cúmplala. Si tiene cuidado de usar los mismos nombres que los nombres de sus clases en sus funciones x Fromy , será mucho más fácil recordar qué nombres usó. Por supuesto, este patrón no funciona para todo, pero funciona donde está escribiendo código que puede considerarse "funcional".

Joel Spolsky
fuente
Un buen recordatorio de que en los idiomas OOP, los nombres de clase no siempre tienen que ser sustantivos, pero en ocasiones está bien que sean "verbales". Por eso los practicantes de OOP a menudo se tropiezan (como la persona que hace la pregunta) ya que enfatizan demasiado que las clases deben ser una "cosa" en el mundo real.
Ray
77
La xFromY-Convetion básicamente repite lo que hay en el tipo de retorno y la lista de parámetros: Foo fooFromBar (barra de barras). Depende de usted si llama a esto consistencia o redendencia.
Lena Schimmel
"En su caso, parece que su clase transforma una URL en un documento". ¿Desde cuándo se supone que las clases "hacen" cosas, en lugar de representar conceptos?
user51568
66
@Brian: solo es redundante en un lugar ... en la declaración. En cualquier otro lugar donde lo use, es bueno tener un pequeño recordatorio de los tipos de datos. Hace que el código sea más legible sin tener que volver a la declaración.
Joel Spolsky
3
@ stefan: en algunos lenguajes, como C # y Java, todo el código debe encapsularse en una clase a diferencia de C ++. Las funciones no son ciudadanos de primera clase en esos idiomas si desea modularizar el código. Por lo tanto, a veces terminas con una clase que podría "hacer" cosas como una función.
Ray
31

A veces no hay un buen nombre para una clase o método, nos sucede a todos. Muchas veces, sin embargo, la incapacidad de encontrar un nombre puede ser un indicio de algo mal con su diseño. ¿Tu método tiene demasiadas responsabilidades? ¿Su clase encapsula una idea coherente?

Brad Barker
fuente
3
Muy buen punto, de verdad.
Camilo Martin
27

Hilo 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 
         }
    }
}

Hilo 2:

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

No hay Thread.sleep (...) en ninguna parte aquí.

krosenvold
fuente
24

También paso mucho tiempo preocupándome por los nombres de cualquier cosa que pueda recibir un nombre cuando estoy programando. Sin embargo, diría que vale la pena. A veces, cuando estoy atascado, lo dejo por un tiempo y durante un descanso para tomar café, pregunto un poco si alguien tiene una buena sugerencia.

Para su clase, sugeriría VendorHelpDocRequester.

willcodejavaforfood
fuente
1
> VendorHelpDocRequester Buena. En realidad busqué en Google Solicitante en lugar de Solicitante, ambas parecen ser palabras legítimas en inglés.
Haoest
1
Lo he hecho una o dos veces también :)
willcodejavaforfood
1
Tener un verbo en el nombre de la clase siempre me suena mal. Además, siempre conduce a alguna duplicación en el uso (es decir:) VendorHelpDocRequester.request(). Prefiero solo la forma plural como `VendorHelpDocs.request () '
Edson Medina
19

El libro Code Complete de Steve Mcconnell tiene un buen capítulo sobre nombrar variables / clases / funciones / ...

Emile Vrijdags
fuente
ese es uno de mis libros favoritos, lo recomiendo encarecidamente
willcodejavaforfood
2
¡+1 para cualquiera que mencione Code Complete!
Richard Ev
15

Creo que esto es un efecto secundario.

No es el nombre real lo que es difícil. Lo difícil es que el proceso de nombrar te hace enfrentar el horrible hecho de que no tienes idea de qué demonios estás haciendo.

Nosredna
fuente
12

De hecho, acabo de escuchar esta cita ayer, a través del blog Signal vs. Noise en 37Signals, y ciertamente estoy de acuerdo con ella:

"Solo hay dos cosas difíciles en informática: invalidación de caché y nombrar cosas". - Phil Karlton

Jonathan Schuster
fuente
simonwillison.net/2007/Jul/5/hard me llevó a tbray.org/ongoing/When/200x/2005/12/23/UPI que me llevó a karlton.hamilton.com y luego a karlton.hamilton.com/quotes /showallquotes.cgi , que no incluye la cita! (Pero reconozco el n. ° 5 de Scrum.)
Daryl Spitzer
1
"Dos cosas difíciles en Ciencias de la Computación: invalidación de caché, nombrar cosas y errores".
Dan Lugg
7

Es bueno que sea difícil. Te obliga a pensar en el problema y en lo que se supone que debe hacer la clase. Los buenos nombres pueden ayudar a lograr un buen diseño.

JW
fuente
6

Convenido. Me gusta mantener mis nombres y variables de tipo tan descriptivos como sea posible sin ser demasiado horrendos, pero a veces hay un cierto concepto para el que no puedes encontrar una buena palabra.

En ese caso, siempre me ayuda pedirle información a un compañero de trabajo, incluso si en última instancia no ayudan, generalmente me ayuda al menos a explicarlo en voz alta y hacer que mis ruedas giren.

Daniel Schaffer
fuente
6

Estaba escribiendo sobre convenciones de nombres el mes pasado: http://caseysoftware.com/blog/useful-naming-conventions

La esencia de esto:

verbAdjectiveNounStructure - con Structure y Adjective como partes opcionales

Para los verbos , me limito a los verbos de acción: guardar, eliminar, notificar, actualizar o generar. De vez en cuando, uso "proceso" pero solo para referirme específicamente a colas o trabajos atrasados.

Para los sustantivos , uso la clase o el objeto con el que se interactúa. En web2project, a menudo se trata de tareas o proyectos. Si es Javascript interactuando con la página, puede ser cuerpo o tabla. El punto es que el código describe claramente el objeto con el que está interactuando.

La estructura es opcional porque es única para la situación. Una pantalla de listado puede solicitar una Lista o una Matriz. Una de las funciones principales utilizadas en la Lista de proyectos para web2project es simplemente getProjectList. No modifica los datos subyacentes, solo la representación de los datos.

Los adjetivos son algo completamente distinto. Se usan como modificadores del sustantivo. Algo tan simple como getOpenProjects podría implementarse fácilmente con un getProjects y un parámetro de cambio, pero esto tiende a generar métodos que requieren un poco de comprensión de los datos subyacentes y / o la estructura del objeto ... no necesariamente algo que desee alentar. Al tener funciones más explícitas y específicas, puede envolver y ocultar completamente la implementación del código que lo usa. ¿No es ese uno de los puntos de OO?

CaseySoftware
fuente
4

Más que solo nombrar una clase, crear una estructura de paquete adecuada puede ser un desafío difícil pero gratificante. Debe considerar separar las preocupaciones de sus módulos y cómo se relacionan con la visión de la aplicación.

Considere el diseño de su aplicación ahora:

  • App
    • VendorDocRequester (lea del servicio web y proporcione datos)
    • VendorDocViewer (utilice el solicitante para proporcionar documentos del proveedor)

Me aventuraría a adivinar que están sucediendo muchas cosas dentro de unas pocas clases. Si tuviera que refactorizar esto en un enfoque más MVC-ified, y permitir que las clases pequeñas manejen tareas individuales, podría terminar con algo como:

  • App
    • VendorDocs
      • Modelo
        • Documento (objeto simple que contiene datos)
        • WebServiceConsumer (tratar con nitty gritty en el servicio web)
      • Controlador
        • DatabaseAdapter (maneja la persistencia usando ORM u otro método)
        • WebServiceAdapter (utilice Consumer para tomar un documento y pegarlo en la base de datos)
      • Ver
        • HelpViewer (use DBAdapter para escupir la documentación)

Luego, los nombres de sus clases dependen del espacio de nombres para proporcionar un contexto completo. Las clases mismas pueden estar relacionadas inherentemente a la aplicación sin necesidad de decirlo explícitamente. ¡Los nombres de clase son más simples y fáciles de definir como resultado!

Otra sugerencia muy importante: hazte un favor y recoge una copia de Head First Design Patterns. Es un libro fantástico y fácil de leer que lo ayudará a organizar su aplicación y escribir un mejor código. Apreciar los patrones de diseño lo ayudará a comprender que muchos de los problemas que encuentra ya se han resuelto, y podrá incorporar las soluciones a su código.

Mike Griffith
fuente
4

Leo Brodie, en su libro "Thinking Forth", escribió que la tarea más difícil para un programador era nombrar bien las cosas, y afirmó que la herramienta de programación más importante es un tesauro.

Intente usar el diccionario de sinónimos en http://thesaurus.reference.com/ .

Más allá de eso, no use la notación húngara NUNCA, evite las abreviaturas y sea coherente.

Los mejores deseos.

Rob Williams
fuente
1
+1 con la nota de que no debes usar lo que se llama sistema húngaro; La aplicación húngara puede ser útil a veces, especialmente en un lenguaje de programación sin un buen sistema de escritura.
user51568
Nunca he oído hablar de la notación húngara de sistema versus aplicación, pero tampoco es una buena idea en ningún entorno: siempre debe nombrar en función de QUÉ, no de CÓMO, y el húngaro se trata totalmente de cómo.
Rob Williams
@RobWilliams Creo que se referían al artículo de Joel Spolsky
Alois Mahdal
1
@RobWilliams Además, ¿estás seguro de "Nunca he oído hablar de X vs Y, pero tampoco es una buena idea ..." ...? :)
Alois Mahdal
4

En resumen:
estoy de acuerdo en que los buenos nombres son importantes, pero no creo que tenga que encontrarlos antes de implementar a toda costa.

Por supuesto, es mejor tener un buen nombre desde el principio. Pero si no puede encontrar uno en 2 minutos, cambiar el nombre más tarde costará menos tiempo y es la opción correcta desde el punto de vista de la productividad.

Largo:
generalmente no vale la pena pensar demasiado en un nombre antes de implementarlo. Si implementa su clase, denominándola "Foo" o "Dsnfdkgx", mientras implementa, verá lo que debería haberle dado.

Especialmente con Java + Eclipse, cambiar el nombre de las cosas no es nada molesto, ya que maneja cuidadosamente todas las referencias en todas las clases, le advierte sobre colisiones de nombres, etc. Y mientras la clase aún no esté en el repositorio de control de versiones, no lo haré ' Creo que hay algo de malo en renombrarlo 5 veces.

Básicamente, se trata de cómo piensas sobre la refactorización. Personalmente, me gusta, aunque a veces molesta a mis compañeros de equipo, ya que creen en nunca tocar un sistema en ejecución . Y de todo lo que puede refactorizar, cambiar los nombres es una de las cosas más inofensivas que puede hacer.

Lena Schimmel
fuente
3

¿Por qué no HelpDocumentServiceClient es un bocado, o HelpDocumentClient ... no importa que sea un proveedor, el punto es que es un cliente de un servicio web que se ocupa de los documentos de Ayuda?

Y sí, nombrar es difícil.

JoshBerke
fuente
3

Solo hay un nombre razonable para esa clase:

HelpRequest

No permita que los detalles de implementación lo distraigan del significado.

Angus Glashier
fuente
Un año y medio después, estaba a punto de sugerir HelpLibrarypara la clase, pero esto es al menos igual de bueno. ¡Vale la pena leer las respuestas primero!
Jeff Sternal
2

¡Invierta en una buena herramienta de refactorización!

TGnat
fuente
jajaja A veces, la refactorización no es la mejor opción (grandes proyectos de C ++), pero ciertamente he recurrido a ella antes. A veces solo tengo que hacer las cosas, y los nombres me llegan más tarde.
Steve S
2

Me limito a lo básico: VerbNoun (argumentos). Ejemplos: GetDoc (docID).

No hay necesidad de ponerse elegante. Será fácil de entender dentro de un año, ya sea usted u otra persona.

LJ
fuente
Si bien esto se lee bien, se organiza mal porque está al revés. Es mejor decir DocGet () porque cuando también creas DocAdd () DocRemove (), etc., todos aparecerán juntos en una lista. Tu método realmente muestra cuán feo se pone cuando tienes docenas de Gets o no.
TravisO
Excelente sugerencia, TravisO.
Jon Smock el
No usaría un verbo para una clase normalmente.
willcodejavaforfood
2

Para mí no me importa cuánto tiempo es un método o nombre de clase siempre que sea descriptivo y en la biblioteca correcta. Atrás quedaron los días en los que debe recordar dónde reside cada parte de la API.

Intelisense existe para todos los idiomas principales. Por lo tanto, cuando uso una API de terceros, me gusta usar su inteligencia para la documentación en lugar de usar la documentación 'real'.

Con eso en mente, estoy bien para crear un nombre de método como

StevesPostOnMethodNamesBeingLongOrShort

Largo, pero ¿y qué? ¡Quién no usa pantallas de 24 pulgadas en estos días!

Steve
fuente
1

Tengo que aceptar que nombrar es un arte. Se vuelve un poco más fácil si su clase sigue un cierto "patrón de diseño" (fábrica, etc.).

Otávio Décio
fuente
1

Esta es una de las razones para tener un estándar de codificación. Tener un estándar tiende a ayudar a encontrar nombres cuando sea necesario. ¡Ayuda a liberar tu mente para usar en otras cosas más interesantes! (-:

Recomiendo leer el capítulo correspondiente del Código completo de Steve McConnell ( enlace de Amazon ) que incluye varias reglas para ayudar a la legibilidad e incluso a la mantenibilidad.

HTH

salud,

Robar

Rob Wells
fuente
1

¡No, la depuración es lo más difícil para mí! :-)

Estofado S
fuente
la depuración generalmente se reduce a hacer la pregunta correcta. Hay un juego de números en el que tienes que adivinar un número del 1 al 1000. Si tu suposición es demasiado baja o alta, la consola te lo dice y solo tienes 10 intentos. ¿Qué haces?
Haoest
1

DocumentFetcher? Es difícil de decir sin contexto.

Puede ayudar actuar como un matemático y tomar prestado / inventar un léxico para su dominio a medida que avanza: decídase por palabras cortas y simples que sugieran el concepto sin deletrearlo todo el tiempo. Con demasiada frecuencia veo largas frases latinas que se convierten en acrónimos, lo que hace que necesites un diccionario para los acrónimos de todos modos .

Darius Bacon
fuente
1

El lenguaje que usa para describir el problema es el lenguaje que debe usar para las variables, métodos, objetos, clases, etc. En términos generales, los sustantivos coinciden con los objetos y los verbos coinciden con los métodos. Si le faltan palabras para describir el problema, también le falta una comprensión completa (especificación) del problema.

Si solo se trata de elegir entre un conjunto de nombres, entonces debería estar impulsado por las convenciones que está utilizando para construir el sistema. Si ha llegado a un nuevo lugar, descubierto por convenciones anteriores, entonces siempre vale la pena dedicar un poco de esfuerzo para tratar de extenderlos (de manera adecuada y coherente) para cubrir este nuevo caso.

En caso de duda, duerma y elija el primer nombre más obvio a la mañana siguiente :-)

Si un día se despierta y se da cuenta de que estaba equivocado, cámbielo de inmediato.

Pablo.

Por cierto: Document.fetch () es bastante obvio.

Paul W Homer
fuente
1

Me parece que tengo más problemas en las variables locales. Por ejemplo, quiero crear un objeto de tipo DocGetter. Entonces sé que es un DocGetter. ¿Por qué necesito darle otro nombre? Por lo general, termino dándole un nombre como dg (para DocGetter) o temp o algo igualmente no descriptivo.

Jason Baker
fuente
1

No olvide que los patrones de diseño (no solo los de GoF) son una buena manera de proporcionar un vocabulario común y sus nombres deben usarse siempre que se ajuste a la situación. Eso incluso ayudará a los recién llegados que están familiarizados con la nomenclatura a comprender rápidamente la arquitectura. ¿Se supone que esta clase en la que estás trabajando debe actuar como un Proxy, o incluso una Fachada?

Herrmann
fuente
1

¿No debería ser la documentación del proveedor el objeto? Quiero decir, esa es tangible, y no solo como una antropomorfización de una parte de su programa. Por lo tanto, es posible que tenga una VendorDocumentationclase con un constructor que obtenga la información. Creo que si un nombre de clase contiene un verbo, a menudo algo ha salido mal.

Svante
fuente
1

Definitivamente te siento. Y siento tu dolor. Todos los nombres en los que pienso me parecen basura. Todo parece tan genérico y finalmente quiero aprender a inyectar un poco de talento y creatividad en mis nombres, haciendo que realmente reflejen lo que describen.

Una sugerencia que tengo es consultar un Tesauro. Word tiene una buena, al igual que Mac OS X. Eso realmente puede ayudarme a sacar mi cabeza de las nubes y me da un buen punto de partida y algo de inspiración.

John Gallagher
fuente
0

Si el nombre se explica por sí mismo a un programador laico, entonces probablemente no sea necesario cambiarlo.

dreamlax
fuente