Veo preguntas similares a esta 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 por la carcasa en 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, recuerdo un consejo que tomé al leer Code Complete 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 entre nombres de rutina similares. A medida que construye el código, elija nombres con grandes diferencias para evitar el problema.
La firma de mi método tiene mucho "Alcance", por lo 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 fuerte disgusto por esta convención. Agregar un prefijo "my" a nombres de variables no proporciona contexto adicional.
También veo lo siguiente
public Range PadRange(Range rangeToPad) {}
Me gusta más que el prefijo "my", pero en general no me importa. Simplemente se siente demasiado detallado para mí y se lee torpemente como un nombre variable. Para mí, se entiende que el rango se rellenará debido al nombre del método.
Entonces, con todo esto expuesto, mi instinto es ir con la primera firma. Para mí, está limpio. No es necesario forzar el contexto cuando no es necesario. ¿Pero estoy perjudicando a mí mismo o a los futuros desarrolladores con esta convención? ¿Estoy violando una mejor práctica?
fuente
Range range
está bien.Range r
(al menos para un cuerpo de método corto) yRange toPad
.Respuestas:
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 tenido ningún inconveniente real, todo lo contrario.Por supuesto, cuando tiene diferentes variables locales en el mismo alcance, todas del mismo tipo, probablemente sea útil invertir algún esfuerzo mental para distinguirlas adecuadamente.
fuente
Wack(Bozo bozoToBeWacked)
como un ejemplo de redundancia en el nombre de la variable que se expresa ampliamente por el método en sí mismo (y por lo tanto indeseable según la pregunta original).Wack(Person bozo)
Sin embargo, es más semánticamente valioso, ya que implica que se espera que solo se activen los bozos.initialRange
. Todavía es muy genérico, pero no tiene casi el mismo nivel de desagrado quemyRange
.Punch(Bozo punchingBozo, Bozo bozoToBePunched)
. La nomenclatura detallada es más relevante cuando tiene que distinguir entre varias cosas (que se describen semánticamente con casi las mismas palabras). La sugerencia de OPRange rangeToPad
no es necesaria en su ejemplo de método de un parámetro, pero podría ser increíblemente necesario para un método que abarca variosRange
objetos.Punch(Bozo source, Bozo target)
haría el trabajoHago esto todo el tiempo, me da mucha tranquilidad. Si se trata de un argumento pasado a un constructor que debe asignarse a un miembro, mi miembro también se denominará rango y la asignación será
Y normalmente tendría una propiedad llamada Range.
Todos son lo mismo, solo difieren en contexto, por lo que tiene sentido mantener un solo nombre y tendrá que recordar solo un nombre. Es una cosa, las diferencias son puramente técnicas.
Debe ser estricto con los miembros que califiquen completamente con "esto". sin embargo, pero para eso está StyleCop.
Nota lateral de StyleCop
¡Controversia garantizada!
Para aquellos que abogan contra el uso de "esto": he visto _, m, m_ y nada. El lenguaje en sí nos ofrece una forma perfectamente clara, inequívoca y universalmente reconocible de indicar que estamos tratando con un miembro de la clase. ¿Por qué demonios querrías inventar tu propio estilo 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 manera.
"¡Son más personajes!" ¿Seriamente? "¡El tiempo de compilación se disparará!" ¿Seriamente? "¡Tendré que levantar mi dedo 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 insertar un nuevo archivo de código, ejecuto StyleCop y encontrará una cantidad de miembros que carecen de "este" calificador. Puse "esto". en el portapapeles, ejecutado por los miembros e insertar. Sin 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: generalmente te hace quejarse durante una semana o dos y luego te encantará.
fuente
this
excepto cuando sea esencial. Es solo ruido de lo contrario. Úselo_range
para el campo ythis
nunca es necesario excepto en los métodos de extensión._
es preferible al ruido dethis.
? Yo diría que uno tiene un significado impuesto por el lenguaje (y generalmente tiene resaltado de sintaxis) mientras que el otro no.Mi guía personal sobre los métodos, parámetros y variables de denominación es bastante simple:
Por lo tanto, la firma óptima del método, en mi opinión, sería:
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á en el lugar al rellenarse y luego devolverse. En contraste, no se pueden hacer suposiciones sobre una variable llamadarange
.Además, en el cuerpo real del método, cualquier otra
Range
variable que se introduzca se debería (debería) nombrar por su intención, por lo que podría tenerpadded
yunpadded
...toPad
cumplir con esas convenciones de nomenclatura, perorange
simplemente sobresale y no se gelifica.fuente
padded
/unpadded
suena bien para variables locales inmutables. Pero si hay untoPad
parámetro mutable , después de que se haya completado el relleno, el nombretoPad
ya no cabe (a menos que el resultado se devuelva de inmediato). Prefiero seguirRange range
en esos casos.result
. Se modifica y devuelve . El último se desprende del nombre y el primero sigue, ya que devolver un argumento no modificado no tiene sentido.Pad
método devuelve aRange
. Eso, para mí, implica que el que he pasado se conservará, no se modificará en su lugar, yRange
se devolverá un nuevo relleno . .Pad(toPad)
se siente un poco mal en mi humilde opinión. Sin embargo, haces un buen punto para defender tu punto de vista. ¡Obtienes un +0 de mi parte! :)Para nombrar elementos de código (tipos, variables, funciones, cualquier cosa), la pregunta clave que debe hacerse es
Si hago un error tipográfico, ¿el compilador lo encontrará por mí?
El peor tipo de error basado en errores tipográficos es aquel en el que el código se compila y se ejecuta, pero proporciona un comportamiento diferente al esperado, por razones sutiles. Y como se debe a un error tipográfico, generalmente es muy difícil de ver cuando inspecciona el código. Si un error tipográfico detendrá la compilación del código, entonces el compilador marcará la línea que causa el problema, y puede encontrarlo y solucionarlo fácilmente.
Para su situación donde el tipo y la variable difieren solo en mayúsculas, este siempre será el caso. (O casi siempre, con suficiente esfuerzo, estoy seguro de que podría hacerlo funcionar, pero realmente tendría que intentarlo). Así que creo que está bien allí.
Debería preocuparse si hubiera dos variables, métodos, funciones o propiedades en el ámbito actual llamado
range
yRange
. En ese caso, el compilador probablemente lo dejará pasar, y obtendrá un comportamiento inesperado en 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 ser implícitamente 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 tenía dos tipos declarados llamadosrange
yRange
.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 llamadaPRange
, es fácil omitir accidentalmenteP
, por ejemplo. C # debería captar esto, pero C y C ++ solo le darán una advertencia como máximo. O, lo que es más preocupante, suponga que tiene una versión doble llamadaDRange
y reduce la muestra a una versión flotante llamadaFRange
. Utilice el flotador por accidente (que es fácil ya que las claves son adyacentes en un teclado) y su código será tipo de trabajo, sino que va a caer otra vez en formas extrañas e impredecibles cuando se ejecuta el proceso de resolución y el underflow.Ya no estamos en los días en que teníamos límites de nomenclatura de 8 caracteres, o 16 caracteres, o cualquier límite arbitrario. A veces escuché a principiantes quejarse de nombres de variables más largos que hacen que la codificación tarde más. Sin embargo, solo los principiantes se quejan de esto. Los programadores serios saben que lo que realmente lleva tiempo es descubrir errores oscuros, y la mala elección de los nombres es una forma clásica de caer en ese agujero en particular.
fuente
Una anécdota que me gustaría agregar, si bien
Range range
esto es sintácticamente legal, podría hacer que las cosas sean más difíciles de depurar o refactorizar. ¿Busca 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 nombres.Sin embargo, esto depende en gran medida del contexto. Si es un archivo de 30 líneas, mis declaraciones realmente no entran en juego.
fuente
grep
es una gran herramienta, pero no es una herramienta de refactorización. Y existen herramientas de refactorización en cada plataforma de desarrollo que he usado. (OS X, Ubuntu, Windows).Creo que puede usar
Range range
hoy en día por una razón: resaltado de sintaxis. Los IDE modernos generalmente resaltan los nombres de los tipos y los nombres de los parámetros en diferentes colores . Además, un tipo y una variable tienen una considerable "distancia lógica" que no debe confundirse fácilmente.Si este no fuera el caso, consideraría un nombre diferente o trataría de habilitar un complemento / extensión que pueda resaltar esta sintaxis.
fuente
Cuando una función es genérica, es lógico que los parámetros sean genéricos y, por lo tanto, deben tener nombres genéricos.
No es lo que está diciendo, pero he visto funciones que realizan una función genérica que tiene nombres de parámetros que son engañosamente específicos. Me gusta
El nombre de la función suena muy genérico, como esto podría aplicarse a muchas cadenas en muchas situaciones. Pero el nombre del parámetro es extrañamente específico, lo que me hace preguntarme si el nombre de la función es engañoso o ... ¿qué?
Entonces, seguro, en lugar de decir Range range, podría decir Range rangeToPad. Pero, ¿qué información agrega esto? Por supuesto, es el rango de relleno. ¿Qué otra cosa podría ser?
Agregar algún prefijo arbitrario, "my" 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 un nombre de variable sea el mismo que un nombre de tipo, con o sin mayúsculas y minúsculas, a veces pongo un prefijo o un sufijo, solo para que se compile . 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 ();" mil millones de veces y nunca me pareció confuso. (Siempre me ha parecido un poco redundante y prefiero que en VB puedas decir "cliente débil como nuevo cliente" y no tienes que dar el nombre de la clase dos veces).
Donde sí objeto fuertemente a los nombres genéricos es cuando hay dos o más instancias del mismo tipo en la misma función. ESPECIALMENTE parámetros. Me gusta:
¿Cuál es la diferencia entre range1 y range2? ¿Cómo se supone que debo saber? Si es algo donde realmente son dos valores genéricos e intercambiables, está bien, como
Esperaría 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! Estaba trabajando en un programa recientemente 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, esos los nombres realmente me ayudan a determinar cuál es cuál.
fuente