2010-10-15 10 views
5

He respondido a los hilos aquí (o al menos commented) con respuestas que contienen un código como este, pero me pregunto si es buena o mala forma escribir una serie de ramas if con una (o más) ramas haciendo nada en ellos, generalmente para eliminar la comprobación de null en cada rama.¿Es una rama If que no hace nada un olor a código o una buena práctica?

Un ejemplo (código C#):

if (str == null) { /* Do nothing */ } 
else if (str == "SomeSpecialValue") 
{ 
    // ... 
} 
else if (str.Length > 1) 
{ 
    // ... 
} 

en lugar de:

if (str != null && str == "SomeSpecialValue") 
{ 
    // ... 
} 
else if (str != null && str.Length > 1) 
{ 
    // ... 
} 

Y, por supuesto, esto es sólo un ejemplo, ya que tienden a utilizar estos con grandes y más complejos clases Y en la mayoría de estos casos, un valor null indicaría no hacer nada.

Para mí, esto reduce la complejidad de mi código y tiene sentido cuando lo veo. Entonces, ¿esta forma es buena o mala (un código huele, incluso)?

+1

Creo que está bien si hace que su código sea más legible y evita las condiciones intrincadas. Votar para cerrar, sin embargo, "es esto bueno o malo" es demasiado subjetivo. – casablanca

+3

El hecho de que todos estos controles sean necesarios "por si acaso" el valor es nulo es un olor en sí mismo, en mi humilde opinión. Al hacer esto, estás ocultando errores. – SimonJ

+1

@SimonJ: Buen punto. Al menos en este caso, debería lanzar una excepción si no se esperaba un valor 'nulo'. – casablanca

Respuesta

5

de hecho, es bueno para evitar lo siguiente, porque innecesariamente vuelve a verificar una de las condiciones (el hecho de que el compilador optimizar esta distancia no viene al caso - potencialmente marcas más trabajo para las personas que intentan leer su código):

if (str != null && str == "SomeSpecialValue") 
{ 
    // ... 
} 
else if (str != null && str.Length > 1) 
{ 
    // ... 
} 

Pero también es bastante extraño que hacer lo que usted sugiere, a continuación:

if (str == null) { /* Do nothing */ } 
else if (str == "SomeSpecialValue") 
{ 
    // ... 
} 
else if (str.Length > 1) 
{ 
    // ... 
} 

que digo esto es extraño porque ofusca su intención y desafía las expectativas del lector.Si busca una condición, la gente espera que haga algo si está satisfecho, pero no lo está. Esto se debe a que su intención no es realmente proceso de la condición nula, sino más bien para evitar un puntero nulo cuando se echa las dos condiciones que usted está realmente interesa. En efecto, en lugar de tener dos estados conceptuales para manejar, con una provisión de cordura (entrada no nula), en cambio dice que tiene tres estados conceptuales para manejar. El hecho de que, computacionalmente, podría decirse que hay tres de esos estados está al lado del punto, es menos claro.

El enfoque caso habitual en este tipo de situación es como Oren Una sugirió - comprobar la hipótesis nula, y después comprobar las otras condiciones dentro del bloque resultado:

if (str != null) 
{ 
if (str == "SomeSpecialValue") 
{ 
    // ... 
} 
else if (str.Length > 1) 
{ 
    // ... 
} 
} 

Esto es poco más que una cuestión de estilo de mejora de la legibilidad, a diferencia de un problema de olor a código.

EDITAR: Sin embargo, si ya está listo con la condición de no hacer nada, yo hago muy parecida a la que incluyó un comentario "no hacer nada". De lo contrario, la gente podría pensar que simplemente se olvidó de completar el código.

+0

Ver edición - Tomé esa (la cadena "[NULL]") porque la gente estaba obsesionada con eso. – palswim

+0

@palswim Bien. Pero tenga en cuenta que no fue realmente el punto principal de mi respuesta. (Pero al mismo tiempo, ese código vino de alguna parte; si es código de producción, es casi seguro que sea algo malo). – user359996

+0

@ user359996: No; No quería copiar y pegar mi código de producción. Estaba tratando de pensar en un ejemplo sobre el terreno. – palswim

21

prefiero hacerlo así-

if (str != null) 
{ 
if (str == "[NULL]") 
{ 
    // ... 
} 
else if (str.Length > 1) 
{ 
    // ... 
} 
} 

Creo que siempre se puede "reformular" un if con un cuerpo vacío en él es la negación de un cuerpo, y que se ve mejor y tiene más sentido.

+1

Creo que tengo una aversión a demasiada sangría. También me ahorra un poco de espacio vertical, y en C#, al menos, estoy seguro de que el compilador lo manejará bien. – palswim

+1

El compilador lo manejará bien, pero en mi humilde opinión, lo que dices tiene una lógica incómoda. ¿Por qué decir "si ... y luego no hacer nada", cuando puedes decir "si no ... que lo haces ...". Sobre la identación, puedes reducir el número de espacios. la pestaña toma, lo que puede ayudar al menos un poco. –

+2

No querer formatear correctamente el código no es un buen argumento en contra de escribir correctamente el código. – nearlymonolith

2

Su primer ejemplo es perfectamente legible para mí: no huele en absoluto.

4

En este caso particular, voy a volver pronto y que hace que el código más fácil de leer

if (string.IsNullOrEmpty(str)) { return; } 

me gusta poner una declaración explícita de retorno.

+1

Eso solo funciona si la función no hace nada más que el bloque 'if ... else'. – palswim

+0

Esto realmente depende de la semántica del problema. Muy raramente, un argumento nulo significa "no hacer nada". Con demasiada frecuencia significa que alguien ha cometido un error, y al regresar silenciosamente, solo está agravando el problema. Si no es un soporte vital o militar, el fracaso es una buena idea. – user359996

+0

Estoy completamente de acuerdo con usted y siempre fallo rápido. Solo estoy respondiendo a esta pregunta en particular donde el uso por cualquier razón quiere volver. Esto sucede a menudo en el procesamiento por lotes donde, en lugar de fallar, simplemente omita y posiblemente registre qué entidad se saltó. – softveda

2

Todo depende del contexto. Si poner una declaración if vacía hace que el código sea más legible, entonces vaya por eso.

+0

Sí, pero siempre documéntelo cuando lo haga. O bien, si eres como yo y tratas de crear un código que no necesite comentarios y no estés trabajando en un lenguaje que obligue a que todo esté en una clase, llama a un método llamado Nothing(). –

+0

Estoy acostumbrado a trabajar con Python, que tiene 'pass' incluido en él (una declaración para no hacer nada). –

2

Es legible, si es bueno o malo depende de lo que está tratando de lograr - generalmente las declaraciones anónimas de tipo "va por siempre" tipo if son malas. No se olvide de los métodos de cuerda estática horneados en el marco: string.IsNullOrEmpty() y string.IsNullOrWhiteSpace().

Su línea if (str == null) { /* Do nothing */ } es inusual, pero tiene un punto positivo: está dejando que otros desarrolladores sepan de antemano que no está haciendo nada deliberadamente para ese caso, con su larga estructura if/else sus intenciones podrían no ser claras si cambiado a

if (str != null) 
{ 
    /* carry on with the rest of the tests */ 
} 
6

que normalmente poner un return o algo así en la primera if:

void Foo() 
{ 
    if (str == null) { return; } 
    if (str == "SomeSpecialValue") 
    { 
     // ... 
    } 
    else if (str.Length > 1) 
    { 
     // ... 
    } 
} 

Si no puede hacer esto, ya que la función hace algo más después de la if/else, diría es hora de refactorizar, y dividir la parte if/else en una función separada, desde la cual puede regresar temprano.

+0

No me gusta su estilo de sangría, pero esta pieza de código es la mejor manera, en mi humilde opinión, para resolver el problema de OP. +1 – rmeador

+0

@rmeador: Interesante; ¿Qué estilo de sangría te gusta? – palswim

+0

no es realmente "mi" estilo de sangría, solo traté de seguir con los OP. :) – jalf

3

es un olor a código.

Una indicación es que usted pensó en hacer esta pregunta.

Otra indicación es que el código parece incompleto, como si algo debería pertenecer allí. Puede ser legible seguro, pero se siente apagado.

Al leer ese código, un extraño debe detenerse por un segundo y usar la capacidad intelectual para determinar si el código es válido/completo/correcto/como previsto/adjetivo.

user359996 ha puesto el dedo en la cabeza:

que digo esto es extraño porque ofusca su intención y desafía las expectativas del lector.

+0

No creo que "pensar para hacer la pregunta" sea necesariamente un mal indicador. Casi ninguno de los códigos que veo, incluso los ejemplos clásicos de "buen código", me parecen buenos. Casi todos los patrones de diseño me parecen un olor a código, por ejemplo. Casi todos los ejemplos de código de procedimiento me hacen "detenerme por un segundo y usar la capacidad intelectual" para descubrir lo que se pretendía. – Ken

+1

@Ken En general, "pensar para preguntar" puede no ser un signo de olor a código, pero en esta situación yo diría que sí. Si ningún código le parece bien, o está leyendo la fuente incorrecta o, por algún motivo, simplemente no le gusta el aspecto del código. (Muchos) Los patrones de diseño no son olores de código ... exposiciones de debilidad en un lenguaje tal vez. Para el ejemplo anterior, hay cosas mejores para 'detenerse' y gastar energía mental que un código simple que parece incompleto. Lo siento, el código de procedimiento te causa problemas. –

+0

instanceofTom: Lamento que un par de llaves sin ninguna declaración te cause problemas. – Ken

Cuestiones relacionadas