2011-01-23 15 views
23

¿Es realmente una buena práctica evitar el uso del operador NOT en condiciones IF para hacer que su código sea mejor legible? Escuché que if (doSomething()) es mejor que if (!doSomething()).Usando el operador NOT en condiciones IF

+2

"' si (...) '' es mejor que si (...!) '" - Espera, wat? – delnan

+0

La pregunta se ha extendido ligeramente para que quede más claro. – Eugene

+0

Para mí no es el hecho de que uno sea mejor que otro, simplemente debes usar lo que sea apropiado en cada situación, el mundo condicional es muy amplio y diverso. –

Respuesta

32

Realmente depende de lo que estás tratando de lograr. Si no tiene otra cláusula, entonces if(!doSomething()) parece estar bien. Sin embargo, si usted tiene

if(!doSomething()) { 
    ... 
} 
else { 
    // do something else 
} 

probablemente me revertir esa lógica para eliminar el operador ! y hacer que la cláusula if un poco más clara.

+0

+1 Muy cierto eso. –

+1

I (casi) siempre estructuramos si es necesario para que la rama de ejecución más común sea la primera. – Dunes

+1

Existe la regla PMD ConfusingTernary para verificar esto: http://pmd.sourceforge.net/pmd-5.0.3/rules/java/design.html#ConfusingTernary –

11

No, no hay absolutamente nada de malo en usar el operador ! en las declaraciones .

El nombramiento de variables, y en su ejemplo, los métodos es lo que es importante. Si está utilizando:

if(!isPerson()) { ... } // Nothing wrong with this 

Sin embargo:

if(!balloons()) { ... } // method is named badly 

Todo se reduce a la legibilidad. Siempre apunte a lo que es más legible y no se equivocará. Siempre trate de mantener su código continuo también, por ejemplo, mire Bill the Lizards answer.

0

Nunca había oído hablar de este.

Cómo es

if (doSomething()) { 
} else { 
    // blah 
} 

mejor que

if (!doSomething()) { 
    // blah 
} 

La tarde es más clara y concisa.

Además del! el operador puede aparecer en condiciones complejas como (! a || b). ¿Cómo lo evitas entonces?

Use the! operador cuando lo necesite.

+1

usted no está haciendo algo en una condición – Mikey

19

Como afirmación general, es bueno hacer que sus condicionales sean lo más legibles posible. Para su ejemplo, usando! está bien el problema es cuando las cosas se ven como

if ((a.b && c.d.e) || !f) 

es posible que desee hacer algo como

bool isOk = a.b; 
bool isStillOk = c.d.e 
bool alternateOk = !f 

entonces su sentencia if se simplifica a

if ((isOk && isStillOk) || alternateOk) 

Sólo hace que el código sea más legible. Y si tiene que depurar, puede depurar el conjunto isOk de vars en lugar de tener que buscar las variables en el alcance. También es útil para tratar con NPE: dividir el código en fragmentos más simples siempre es bueno.

1

En general, no es una mala idea evitar el! -operator si puede elegir. Una razón simple es que puede ser una fuente de errores, porque es posible pasarla por alto. Más legible puede ser: if (conditionA == false) en algunos casos. Esto principalmente juega un papel si omites la parte else. Si tiene un bloque else de todos modos, no debería usar la negación en la condición if.

excepción de condiciones compuestas así:

if(!isA() && isB() && !isNotC()) 

Aquí usted tiene que utilizar algún tipo de negación para obtener la lógica deseada. En este caso, lo que realmente vale la pena pensar es la denominación de las funciones o variables. Intente nombrarlos para que pueda usarlos a menudo en condiciones simples sin negación.

En este caso, debe pensar en la lógica de isNotC() y si podría reemplazarse por un método isC() si tiene sentido.

Finalmente, su ejemplo tiene otro problema cuando se trata de legibilidad, que es aún más grave que la pregunta si usar negación o no: ¿el lector del código realmente sabe cuándo doSomething() devuelve true y false? Si fue falso, ¿se hizo de todos modos? Este es un problema muy común, que termina en que el lector intente descubrir qué significan realmente los valores de retorno de las funciones.

4

En general,! es un operador de lógica booleana perfectamente bueno y legible. No hay razón para no usarlo a menos que esté simplificando eliminando doble negativos o aplicando la ley de Morgan.

!(!A) = A 

o

!(!A | !B) = A & B 

Como regla general, mantener a la firma de su retorno booleano métodos mnemotécnica y de acuerdo con la convención. El problema con el escenario que @hvgotcodes propone es que, por supuesto, a.b y c.d.e no son ejemplos muy amigables para empezar. Supongamos que tiene una clase de Vuelo y Asiento para una aplicación de reserva de vuelo. Entonces la condición para reservar un vuelo podría ser perfectamente algo como

if(flight.isActive() && !seat.isTaken()) 
{ 
    //book the seat 
} 

Este código perfectamente legible y comprensible. Sin embargo, podría volver a definir su lógica booleana para la clase Seat y reformular la condición a esto.

if(flight.isActive() && seat.isVacant()) 
{ 
    //book the seat 
} 

Eliminando así! operador si realmente te molesta, pero verás que todo depende de lo que signifiquen tus métodos booleanos.

1

tratan como esto

if (!(a | b)) { 
    //blahblah 
} 

Es lo mismo con

if (a | b) {} 
else { 
    // blahblah 
} 
Cuestiones relacionadas