De algunos proyectos de código abierto, reuní el siguiente estilo de codificación
void someFunction(bool forget);
void ourFunction() {
someFunction(false /* forget */);
}
Siempre tengo dudas sobre lo que false
significa aquí. ¿Significa "olvidar", o "olvidar" se refiere a su parámetro correspondiente (como en el caso anterior), y "falso" tiene la intención de negarlo?
¿Qué estilo se usa con mayor frecuencia y cuál es la mejor manera (o algunas de las mejores) para evitar la ambigüedad?
coding-style
comments
boolean
Johannes Schaub - litb
fuente
fuente
someFunction(forget: true);
true
afalse
no actualizar el comentario. Si no puede cambiar la API, entonces la mejor manera de comentar esto essomeFunction( false /* true=forget, false=remember */)
sortAscending
ysortDescending
/ o similares). Ahora, por dentro , ambos pueden llamar al mismo método privado, que podría tener este tipo de parámetro. En realidad, si el lenguaje lo soportara, probablemente lo que pasaría sería una función lambda que contuviera la dirección de clasificación ...Respuestas:
En el código de muestra que publicó, parece que
forget
es un argumento de bandera. (No puedo estar seguro porque la función es puramente hipotética).Los argumentos de la bandera son un olor a código. Indican que una función hace más de una cosa, y una buena función debe hacer solo una cosa.
Para evitar el argumento de la bandera, divida la función en dos funciones que expliquen la diferencia en el nombre de la función.
Argumento de la bandera
Sin argumento de bandera
editar: Idealmente, no es necesario que mantengas una función con el parámetro flag en absoluto. Hay casos similares a los que Fowler llama una implementación enredada donde la separación completa de las funciones crea código duplicado. Sin embargo, cuanto mayor es la complejidad ciclomática de la función parametrizada, más fuerte es el argumento para deshacerse de ella.
Esto es solo una corazonada, pero un parámetro llamado
forget
suena como la envidia de la característica. ¿Por qué una persona que llama le dice a otro objeto que olvide algo? Puede haber un problema de diseño más grande.fuente
serveTraditionalIceCream
yserveLowFatIceCream
cómo se ven? Tengo una enumeración con 14 tipos de helados.En palabras simples:
false
es un literalfalse
someFunction
que no olvidessomeFunction
que el parámetro olvidar esfalse
someFunction
que recuerdesEn mi opinión, sería mejor si la función fuera así:
lo puedes llamar
o mantenga el nombre anterior pero cambie la función de contenedor a
EDITAR:
Como dijo @Vorac, siempre esfuérzate por usar palabras positivas. La doble negación es confusa.
fuente
remember
, a menos que el nombre de la función haga que el significado searemember
muy obvio.rememberToCleanUp* or *persist
o algo.El parámetro puede estar bien nombrado; Es difícil saberlo sin saber el nombre de la función. Asumo que el comentario fue escrito por el autor original de la función, y fue un recordatorio de lo que pasa
false
ensomeFunction
los medios, pero para cualquiera que venga a lo largo después, que es un poco confuso a primera vista.El uso de un nombre de variable positivo (sugerido en Code Complete ) puede ser el cambio más simple que haría que este fragmento sea más fácil de leer, p. Ej.
luego se
ourFunction
convierte en:Sin embargo, el uso de una enumeración hace que la llamada de función sea aún más fácil de entender, a expensas de algún código de soporte:
Si no puede cambiar la firma
someFunction
por alguna razón, el uso de una variable temporal también hace que el código sea más fácil de leer, algo así como simplificar los condicionales al introducir una variable sin otra razón que hacer que el código sea más fácil de analizar por humanos .fuente
remember
en verdadero significa olvidar (en su ejemplo desomeFunction(true /* forget */);
)?enum
es, con mucho, la mejor solución. El hecho de que un tipo pueda representarse como unbool
—es decir, son isomórficos— no significa que deba representarse como tal. El mismo argumento se aplica astring
e inclusoint
.Cambie el nombre de la variable para que tenga sentido un valor bool.
Esto es un millón de veces mejor que agregar un comentario para explicar los argumentos de una función porque el nombre es ambiguo.
fuente
Cree un booleano local con un nombre más descriptivo y asígnele el valor. De esa manera el significado será más claro.
Si no puede cambiar el nombre de la variable, entonces el comentario debería ser un poco más expresivo:
fuente
/* forget */
comentario está ahí para abordar, y es que sin la declaración de la función frente a usted, puede ser difícil recordar lo que se está configurandofalse
. (Es por eso que creo que el consejo de @ Esailija para agregar una enumeración es mejor, y por qué me encantan los idiomas que permiten parámetros con nombre.)Hay un buen artículo que menciona esta situación exacta ya que se refiere a las API Qt-Style. Allí, se llama The Boolean Parameter Trap y vale la pena leerlo.
La esencia de esto es:
fuente
Este es un comentario extraño.
Desde la perspectiva del compilador,
someFunction(false /* forget */);
es en realidadsomeFunction(false);
(el comentario se elimina). Entonces, todo lo que hace esa línea es llamarsomeFunction
con el primer (y único) argumento establecido enfalse
./* forget */
es solo el nombre del parámetro. Probablemente no sea más que un recordatorio rápido (y sucio), que realmente no necesita estar allí. Simplemente use un nombre de parámetro menos ambiguo, y no necesitará el comentario en absoluto.fuente
Uno de los consejos del código Clean es minimizar el número de comentarios innecesarios 1 (porque tienden a pudrirse) y nombrar las funciones y los métodos correctamente.
Después de eso, simplemente eliminaría el comentario. Después de todo, los IDE modernos (como eclipse) muestran un cuadro con código cuando coloca el mouse sobre la función. Ver el código debería aclarar la ambigüedad.
1 Comentando algún código complejo está bien.
fuente
Para aclarar lo obvio, los comentarios pueden mentir. Por lo tanto, siempre es mejor hacer que el código de auto-documentación sin tener que recurrir a los comentarios de explicar, porque una persona (tal vez) cambiará
true
afalse
no actualizar el comentario.Si no puede cambiar la API, recurro a 2 opciones
fuente
me gusta la respuesta acerca de hacer que el comentario sea siempre verdadero , pero si bien es bueno, creo que pierde el problema fundamental con este código: se llama con un literal.
Debe evitar el uso de literales al llamar a métodos. Variables locales, parámetros opcionales, parámetros con nombre, enumeraciones: la mejor manera de evitarlos dependerá del idioma y de lo que esté disponible, pero trate de evitarlos. Los literales tienen valores, pero no tienen significado.
fuente
En C #, utilicé parámetros con nombre para aclarar esto
O
enum
:O sobrecargas:
O polimorfismo »:
fuente
La denominación siempre debe resolver la ambigüedad de los booleanos. Siempre nombro algo booleano como 'isThis' o 'shouldDoThat', por ejemplo:
y así. Pero cuando hace referencia al código de otra persona, es mejor dejar un comentario al pasar valores.
fuente