¿Se considera una mala práctica el uso de nombres de parámetros que difieren de los nombres de tipo solo por el uso de carcasas?

43

Veo preguntas similares a esto con respecto a los nombres de parámetros que coinciden con las propiedades de la clase, pero no puedo encontrar nada con respecto al uso de un nombre de parámetro que sea el mismo que el nombre del tipo de parámetro, excepto en el caso de C #. No parece ser una violación que pueda encontrar, pero ¿se considera una mala práctica? Por ejemplo, tengo el siguiente método

public Range PadRange(Range range) {}

Este método toma un rango y devuelve un nuevo rango al que se le ha aplicado algo de relleno. Entonces, dado el contexto genérico, no puedo pensar en un nombre más descriptivo para el parámetro. Sin embargo, me recuerda un consejo que recogí al leer el Código completo sobre "distancia psicológica". Dice

  

La distancia psicológica se puede definir como la facilidad con la que se pueden diferenciar dos elementos ... Al depurar, prepárese para los problemas causados por una distancia psicológica insuficiente entre nombres de variables similares y nombres de rutinas similares. A medida que construye el código, elija nombres con grandes diferencias para evitar el problema.

La firma de mi método tiene un montón de "Rango" en marcha, así que parece que puede ser un problema con respecto a esta distancia psicológica. Ahora, veo que muchos desarrolladores hacen lo siguiente

public Range PadRange(Range myRange) {}

Personalmente tengo un gran disgusto por esta convención. Agregar un prefijo "mi" a los nombres de variables no proporciona un contexto adicional.

También veo lo siguiente

public Range PadRange(Range rangeToPad) {}

Me gusta esto más que el prefijo "my", pero aún no me importa en general. Simplemente se siente demasiado verboso para mí, y se lee torpemente como un nombre de variable. Para mí, se entiende que el rango se rellenará debido al nombre del método.

Así que con todo esto dispuesto, mi instinto es ir con la primera firma. Para mí, está limpio. No hay necesidad de forzar el contexto cuando no es necesario. Pero, ¿me estoy haciendo daño a mí mismo oa los futuros desarrolladores con esta convención? ¿Estoy violando una buena práctica?

    
pregunta Jason Tyler 19.04.2018 - 17:41

7 respuestas

100

No pienses demasiado en esto, Range range está bien. Utilizo este tipo de nombres durante más de 15 años en C #, y probablemente mucho más tiempo en C ++, y nunca he experimentado ningún inconveniente real, sino todo lo contrario.

Por supuesto, cuando tiene diferentes variables locales en el mismo ámbito, todas del mismo tipo, probablemente ayude a invertir algún esfuerzo mental para distinguirlas correctamente.

    
respondido por el Doc Brown 19.04.2018 - 17:45
17

Hago esto todo el tiempo, me está dando gran tranquilidad. Si es un argumento que se pasa a un constructor que debe asignarse a un miembro, a mi miembro también se le asignará un rango de rango y la asignación sería

this.range = range;

Y normalmente tendría una propiedad llamada Range.

Todos son lo mismo, solo se diferencian en el contexto, por lo que tiene sentido mantener un solo nombre y tendrás que recordar solo un nombre. Una cosa es que las diferencias son puramente técnicas.

Debes ser estricto con los miembros que califican completamente con "esto". aunque, pero para eso es StyleCop.

Nota al margen de StyleCop

¡Controversia garantizada!

Para aquellos que abogan contra el uso de "esto": He visto _, m, m_ y simplemente nada. El lenguaje en sí mismo nos ofrece una manera perfectamente clara, inequívoca y universalmente reconocible de indicar que estamos tratando con un miembro de la clase. ¿Por qué demonios querrías inventarte a tu manera que mutila nombres ya perfectos?

La única razón por la que puedo pensar es que es un hábito heredado de la era C, cuando en realidad tenía sentido hacerlo porque no había otra forma.

"¡Es más personajes!" ¿Seriamente? "¡El tiempo de compilación se disparará!" ¿Seriamente? "¡Tendré que levantar mi meñique cuando lo escriba!". Como si el tiempo de escritura tuviera algún significado en el tiempo total de desarrollo.

Reconozco que cualquier estilo diferente al que estás acostumbrado generará cierta oposición. Pero usar esto consistentemente es difícil de discutir. Así es como funciona para mí: antes de presionar un nuevo archivo de código, ejecuto StyleCop y encontraré un número de miembros que carecen de los calificadores de "this". Pongo "esto". en el portapapeles, ejecutado por los miembros e insertar. Ningún esfuerzo en absoluto.

StyleCop hace mucho más que esto (jaja). Hay muchas maneras en que un desarrollador puede (solo considerando el formato del código) frustrar el trabajo de mantenimiento de su sucesor. StyleCop previene la mayoría de ellos. Es invaluable.

Si eres nuevo en esto: normalmente te hace quejarte por una semana o dos y luego te encantará.

    
respondido por el Martin Maat 19.04.2018 - 21:17
9

Mi auto-orientación sobre los métodos, parámetros y variables de nomenclatura es bastante simple:

  1. Si el nombre contiene el tipo que se pasa o se devuelve, lo estás haciendo mal.
  2. Nombre las cosas por lo que están destinadas, no por lo que son.
  3. Recuerde siempre que el código se lee más de lo que está escrito.

Por lo tanto, la firma del método óptimo, en mi opinión, sería:

Range Pad(Range toPad)

Acortar el nombre del método se explica por sí mismo.

El nombre del parámetro toPad le dice inmediatamente al lector que ese parámetro probablemente se modificará in situ al ser rellenado y luego devuelto. En contraste, no se pueden hacer suposiciones acerca de una variable llamada range .

Además, en el cuerpo real del método, cualquier otra variable Range que se introduzca sería (debería) ser nombrada por su intención, por lo que podría tener padded y unpadded ... toPad conforme a esas convenciones de nomenclatura, pero range simplemente sobresale y no se queda atrás.

    
respondido por el Ian Kemp 20.04.2018 - 08:22
3

Para la denominación de elementos de código (tipos, variables, funciones, cualquier cosa), la pregunta clave es:

Si hago un error tipográfico, ¿el compilador lo encontrará para mí?

El peor tipo de error basado en errores tipográficos es uno en el que el código se compila y ejecuta, pero ofrece un comportamiento diferente de lo que se espera, por razones sutiles. Y como se debe a un error tipográfico, generalmente es muy difícil de ver cuando se está inspeccionando el código. Si un error tipográfico detendrá la compilación del código, el compilador marcará la línea causando el problema, y podrá encontrarlo y solucionarlo fácilmente.

Para su situación en la que el tipo y la variable difieren solo en el uso de mayúsculas, este siempre será el caso. (O casi siempre, con el esfuerzo suficiente, estoy seguro de que podrías hacerlo funcionar, pero realmente deberías intentarlo). Así que creo que estás bien allí.

Lo que le preocuparía sería si hubiera dos variables, métodos, funciones o propiedades en el ámbito actual denominadas range y Range . En ese caso, el compilador probablemente lo dejará y obtendrá un comportamiento inesperado en el tiempo de ejecución. Tenga en cuenta que son dos de cualquiera de esos tipos de elementos de código, no solo "dos variables" o "dos funciones"; todas ellas pueden estar implícitamente unidas entre sí, con la carnicería resultante cuando se ejecuta. Puede recibir advertencias, pero no puede garantizar nada más que eso. Tiene problemas similares si tiene dos tipos declarados llamados range y Range .

También tenga en cuenta que lo mismo se aplica al estilo de notación húngara , donde los nombres tienen el prefijo de uno o más caracteres para decir algo más sobre lo que sea. Si tiene una variable llamada Range y un puntero a ella llamado PRange , es fácil perder accidentalmente el P , por ejemplo. C # debería detectar esto, pero C y C ++ solo te darán una advertencia a lo sumo. O, lo que es más preocupante, suponga que tiene una versión doble llamada DRange y la reduce a una versión flotante llamada FRange . Use el flotador por accidente (lo cual es fácil ya que las teclas están adyacentes en un teclado) y su código funcionará , pero se caerá de formas extrañas e impredecibles cuando se agote el proceso de resolución y desbordamientos.

Ya no estamos en los días en que teníamos límites de denominación de 8 caracteres, o 16 caracteres, o cualquier límite arbitrario. A veces escucho a novatos quejarse de nombres de variables más largos que hacen que la codificación tarde más. Sin embargo, solo los novicios se quejan de esto. Los programadores serios saben que lo que realmente lleva tiempo es descubrir errores ocultos, y la mala elección de nombres es una forma clásica de caer en ese agujero en particular.

    
respondido por el Graham 20.04.2018 - 12:51
1

Una anécdota que me gustaría agregar, mientras que Range range esto es sintácticamente legal, podría hacer las cosas más difíciles de depurar o refactorizar. ¿Está buscando esa variable llamada "rango" en un archivo con muchas variables de tipo Rango? Puede terminar haciendo más trabajo más tarde como resultado de esta elección de nombre.

Sin embargo, esto depende en gran medida del contexto. Si es un archivo de 30 líneas, mis declaraciones realmente no entran en juego.

    
respondido por el Jacob M. 19.04.2018 - 23:53
1

Creo que puedes usar Range range en la actualidad por una razón: el resaltado de sintaxis. Los IDEs modernos generalmente resaltan los nombres de tipo y los nombres de parámetros en diferentes colores . Además, un tipo y una variable tienen una "distancia lógica" considerable que no se puede confundir fácilmente.

Si este no fuera el caso, consideraría un nombre diferente o tratar de habilitar un complemento / extensión que pueda hacer este resaltado de sintaxis.

    
respondido por el akaltar 20.04.2018 - 01:04
0

Cuando una función es genérica, es lógico que los parámetros sean genéricos y, por lo tanto, deberían tener nombres genéricos.

No es lo que estás diciendo, pero he visto funciones que realizan una función genérica que tienen nombres de parámetros que son engañosamente específicos. Me gusta

public String removeNonDigits(String phoneNumber)

El nombre de la función suena muy genérico, ya que esto podría aplicarse a muchas cadenas en muchas situaciones. Pero el nombre del parámetro es extrañamente específico, por lo que me pregunto si el nombre de la función es engañoso, o ... ¿qué?

Tan seguro, en lugar de decir Rango de rango, se podría decir Range rangeToPad. Pero, ¿qué información agrega esto? Por supuesto que es el rango para pad. ¿Qué otra cosa podría ser?

Al agregar un prefijo arbitrario, "mi" o "m_" o lo que sea, transmite cero información adicional al lector. Cuando he usado idiomas en los que el compilador no permite que el nombre de una variable sea el mismo que el nombre de un tipo, con o sin distinción de mayúsculas, a veces puse un prefijo o un sufijo, solo para compilarlo . Pero eso es solo para satisfacer al compilador. Se podría argumentar que incluso si el compilador puede distinguir, esto hace que sea más fácil para un lector humano distinguir. Pero wow, en Java he escrito declaraciones como "Cliente cliente = nuevo Cliente ()"; Un billón de veces y nunca lo encontré confuso. (Siempre lo he encontrado un poco redundante y me gusta que en VB solo pueda decir "atenuar al cliente como nuevo cliente" y no tiene que dar el nombre de la clase dos veces).

Donde I DO se opone fuertemente a nombres genéricos es cuando hay dos o más instancias del mismo tipo en la misma función. ESPECIALMENTE los parámetros. Me gusta:

public Range pad(Range range1, Range range2)

¿Cuál es la diferencia entre rango1 y rango2? ¿Cómo se supone que debo saber? Si es algo donde realmente son dos valores genéricos e intercambiables, está bien, como

public boolean overlap(Range range1, Range range2)

Espero que devuelva verdadero si los rangos se superponen y falso si no lo hacen, por lo que son genéricos e intercambiables.

Pero si son diferentes, ¡dame una pista de cómo son diferentes! Recientemente estaba trabajando en un programa que tenía una clase de "Lugar" para almacenar datos sobre lugares geográficos, y con variables de este tipo llamadas "p", "lugar", "lugar2", "myPlace", etc. Wow, esas Los nombres realmente me ayudan a determinar cuál es cuál.

    
respondido por el Jay 22.04.2018 - 01:44

Lea otras preguntas en las etiquetas