¿Por qué el uso de conjunciones en nombres de métodos es una convención de nomenclatura incorrecta? [cerrado]

12

En mi equipo, trabajamos en estrecha colaboración con algunos arquitectos de software. Aprueban todas las decisiones de diseño de nuestros proyectos, hacen algunas revisiones de código, etc.

Nuestros proyectos consisten principalmente en la funcionalidad de backend implementada en PHP utilizando el marco de Symfony 2. Entonces, sintácticamente, el código, las convenciones de nomenclatura y la estructura del proyecto se ven casi idénticos a lo que sería Java (Symfony 2 fomenta dicha estructura). Menciono esto porque las convenciones específicas de Java también se aplican en nuestro caso (si es posible).

Recientemente, sugirieron algo que me parece muy extraño: todos los métodos deben tener conjunciones en su nombre getEntityOrNull, por ejemplo , setValueOrExceptionetc.

Tal convención de nomenclatura me parece muy incorrecta, pero no puedo presentar ningún argumento concreto o artículos / páginas en línea que lo desafíen específicamente.

Lo único que se me ocurrió es:

  • dicha información debe estar presente en las anotaciones del método, como @returno@throws
  • El uso de conjunciones ("y", "o" etc.) en los nombres de los métodos generalmente sugiere que el Principio de Responsabilidad Única no se respeta adecuadamente

¿Cuáles son algunos otros argumentos concretos contra esta convención de nomenclatura?

Radu Murzea
fuente
en general, no se puede
mosquito
55
the use of conjunctions ("and", "or" etc.) in method names usually suggest that the Single Responsibility Principle is not properly respectedEste no es el caso de los ejemplos que enumeró, donde la conjunción se usa para aclarar el mecanismo utilizado para manejar fallas, no para indicar que puede hacer una cosa u otra. Incluso la función más definida puede tener condiciones de falla legítimas, por ejemplo, abrir una pila vacía.
Doval
44
Considere: (1) usar "opcional" en lugar de "o nulo". "GetOptionalEntity" me suena mejor que "GetEntityOrNull". (2) la biblioteca de clases base .NET usa la convención de que si tiene dos métodos que difieren solo en lo que arrojan, nombre el que no puede lanzar "TryBlah". Por ejemplo, Int32.TryParsey Int32.Parse- ambos analizan una cadena en un número entero, pero el primero devuelve un Booleano que indica éxito y el segundo arroja el fracaso.
Eric Lippert
No usaría un sufijo para la variante de lanzamiento, pero usaría uno para la variante de retorno nulo. Podría ser Try..., ...OrNull, ...OrDefault. @EricLippert Esa no es la única convención en .net. Considere Singlevs. SingleOrDefault, que está muy cerca OrNulldel OP sugerido.
CodesInChaos

Respuestas:

11

Probablemente lo estén haciendo debido a conflictos de nombres. Supongo que no puede tener dos métodos nombrados getEntity, uno que posiblemente arroje una excepción y otro que regrese null. Por lo tanto, debe nombrarlos en consecuencia.

Por mi parte, no me gusta la práctica de tener muchas formas diferentes de llamar al mismo método a menos que esté realizando alguna alteración que solo esa clase en particular puede realizar.

En otras palabras, si getValueOrNullsimplemente está llamando getValueOrException, capturando la excepción y, en ese caso null, regresando , la persona que llama puede realizar esto. Abarrota la clase con métodos que realmente no aportan nada útil. Más bien preferiría el getValue, y sé que arroja la excepción. Mejor aún, preferiría saber que todos los métodos get pueden generar excepciones, y ninguno de ellos regresa nullen su lugar, de modo que el comportamiento sea uniforme en todo mi proyecto, o inversamente, todos potencialmente regresan null, y saber que la persona que llama tendría que lanzar una excepción si que fueron deseados

Sin embargo, también es cierto que no estás a cargo de eso. Mi consejo es mencionarlo, pero no te preocupes por las cosas pequeñas. En última instancia, la responsabilidad de tales convenciones de nombres recae sobre sus hombros, independientemente de si toman o no su consejo, y debido a que son sus culos en la línea, creo que es su prerrogativa decir que no, en mi humilde opinión.

Neil
fuente
Si tuviera que elegir solo uno, es mejor regresar null(o mejor aún, un tipo Opcional / Quizás) ya que lanzar es relativamente costoso. Escribir un asistente que verifique si un valor no es válido y arroja no agrega mucha sobrecarga. Sin embargo, cuando desee la versión sin lanzamiento, tragar la excepción no le devolverá el golpe de rendimiento que recibió al lanzarla.
Doval
1
@Doval Buen punto, y quizás lo más importante, las excepciones deberían ser excepcionales . Si a menudo arrojas excepciones, no las estás usando correctamente. El único problema con la devolución nulles que en nullrealidad puede ser una devolución válida en algunos casos, por lo que tendría que desviarse de la norma y lanzar una excepción en tales casos.
Neil
3

Aunque el uso de conjunciones a menudo indica una violación del SRP, en este caso solo indica el valor de retorno del tipo de datos algebraicos de un pobre que puede ser uno de dos valores, ya sea nullun valor de "éxito".

Están utilizando una especie de notación húngara para compensar las debilidades en el sistema de tipos, es decir, la falta de tipos no anulables. En otras palabras, no hay forma de especificar en su @returnanotación que la función nunca volverá null, y por el contrario, no hay forma de especificar en su @returnanotación que la función posiblemente regrese null.

Además, creo que las @throwsanotaciones no son obligatorias en php, por lo que la ausencia de la anotación no indica la ausencia de una excepción, aunque eso se resuelve mejor haciendo que la anotación sea obligatoria en su guía de estilo.

Dadas esas limitaciones del lenguaje que está utilizando, no es un estilo completamente irracional.

Karl Bielefeldt
fuente
2

En mi código, a veces creo pares de métodos con nombres como getEntity () y getEntityOrNull (). El nombre deja claro el comportamiento esperado. Si getEntity () no encuentra ninguna entidad, se genera una excepción. getEntityOrNull () devolverá un valor nulo.

Al hacer esto, el código de llamada se vuelve un poco más claro. Si el código de llamada tiene que tener una entidad, getEntity hará el truco. Si la entidad es algún tipo de thingee opcional, getEntityOrNull es el método de elección.

Lo mismo podría lograrse con un solo método, pero que luego transfiere parte de la carga al programa de llamadas. Siempre necesita probar un valor nulo o necesita un bloque try / catch. De cualquier manera, es un código adicional que debe duplicarse cada vez que se llama al método.

Si sus arquitectos no están utilizando este tipo de pares de métodos, entonces sí, cuestionaría la necesidad del sufijo.

Nunca vi realmente un método setValueOrException. No puedo pensar en un buen caso de uso común para eso.

Puede considerar preguntar a los arquitectos por qué. Los que conozco siempre se complacen en explicar sus decisiones. A menudo con gran detalle (y a veces insoportable).

Cerad
fuente
Que getEntity arroje una excepción en caso de falla no está del todo claro para mí, esperaría un NULL simple.
Elise van Looij
1

Tus dos argumentos son sólidos. Pero si ellos son los encargados de decidir la convención de nomenclatura, trate de no sentirse tan mal por ser algo con lo que no está de acuerdo.

Mientras lo hace, debe convencerlos de que no usen las porciones "get" y "set" a menos que esos métodos realmente establezcan u obtengan una variable miembro.

Eben
fuente