2011-01-23 10 views
23

È davvero buona norma evitare di utilizzare l'operatore NOT in condizioni IF al fine di rendere il codice più leggibile? Ho sentito il if (doSomething()) è meglio quindi if (!doSomething()).Utilizzo dell'operatore NOT in condizioni IF

+2

"' se (...) '' è meglio di se (...!) '" - Aspetta, wat? – delnan

+0

La domanda è stata leggermente ampliata per renderlo più chiaro. – Eugene

+0

Per me non è il fatto di essere migliori degli altri, semplicemente è necessario usare quale sia appropriato in ogni situazione, il mondo condizionale è molto ampio e diversificato. –

risposta

32

Dipende davvero da ciò che stai cercando di realizzare. Se non ci sono altre clausole allora if(!doSomething()) sembra soddisfacente. Tuttavia, se si dispone di

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

probabilmente sarei invertire tale logica per rimuovere l'operatore ! e rendere la clausola if un po 'più chiaro.

+0

+1 Molto vero. –

+1

I (quasi) struttura sempre se Els in modo che il ramo più comune di esecuzione viene prima. – Dunes

+1

Esiste la regola PMD ConfusingTernary per verificare ciò: http://pmd.sourceforge.net/pmd-5.0.3/rules/java/design.html#ConfusingTernary –

11

No, non c'è assolutamente niente di sbagliato con l'utilizzo l'operatore ! in if..then..else dichiarazioni.

La denominazione delle variabili e, nel tuo esempio, i metodi è l'importante. Se si sta utilizzando:

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

Tuttavia:

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

Tutto si riduce alla leggibilità. Cerca sempre ciò che è più leggibile e non sbaglierai. Cerca sempre di mantenere il tuo codice continuo, ad esempio, guarda Bill the Lizards answer.

0

Non ho mai sentito parlare di questo prima.

Come è

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

meglio di

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

Il secondo è più chiaro e conciso.

Oltre il! l'operatore può apparire in condizioni complesse come (! a || b). Come lo eviti allora?

Utilizzare il! operatore quando è necessario.

+1

non stai facendo qualcosa in una condizione – Mikey

19

Come una dichiarazione generale, è bene rendere i condizionali if il più leggibili possibile. Per il tuo esempio, usando! è ok il problema è quando le cose sembrano

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

si potrebbe desiderare di fare qualcosa di simile

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

allora la vostra istruzione if è semplificata al

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

Rende solo il codice più leggibile. E se devi eseguire il debug, puoi eseguire il debug del gruppo isOk di vars invece di dover scavare attraverso le variabili nell'ambito. È anche utile per trattare con gli NPE: la suddivisione del codice in blocchi più semplici è sempre buona.

1

In genere non è una cattiva idea evitare il! -operator se si ha la scelta. Un motivo semplice è che può essere una fonte di errori, perché è possibile trascurarlo. Più leggibile può essere: if (conditionA == false) in alcuni casi. Questo gioca principalmente un ruolo se salti la parte opposta. Se si ha un altro blocco in ogni caso, non si dovrebbe usare la negazione nella condizione di if.

Fatta eccezione per-condizioni composto come questo:

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

Qui bisogna utilizzare una sorta di negazione per ottenere la logica desiderata. In questo caso, ciò che vale davvero la pena di pensare è la denominazione delle funzioni o delle variabili. Prova a chiamarli in modo da poterli usare spesso in condizioni semplici senza negazione.

In questo caso si dovrebbe pensare alla logica di isNotC() e se potrebbe essere sostituita da un metodo isC() se ha senso.

Infine, il tuo esempio ha un altro problema quando si tratta di leggibilità che è ancora più grave della domanda se usare o meno la negazione: il lettore del codice sa davvero quando doSomething() restituisce true e false? Se era falso era fatto comunque? Questo è un problema molto comune, che finisce nel lettore cercando di scoprire cosa significano veramente i valori di ritorno delle funzioni.

4

In generale,! è un operatore logico booleano perfettamente funzionante e leggibile. Non c'è motivo per non usarlo a meno che tu non stia semplificando rimuovendo i doppi negativi o applicando la legge di Morgan.

!(!A) = A 

o

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

Come regola generale, mantenere la firma del vostro metodi di ritorno booleano mnemonico e in linea con la convenzione. Il problema con lo scenario proposto da @hvgotcodes è che ovviamente a.b e c.d.e non sono esempi molto amichevoli da cui partire. Supponiamo che tu abbia una classe di volo e di volo per un'applicazione di prenotazione del volo. Poi la condizione per prenotare un volo potrebbe perfettamente essere qualcosa come

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

Questo codice perfettamente leggibile e comprensibile. Puoi ridefinire la tua logica booleana per la classe Seat e riformulare la condizione a questo, però.

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

Rimuovendo così il! operatore se ti infastidisce davvero, ma vedrai che tutto dipende da cosa significano i tuoi metodi booleani.

1

provare come questo

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

E 'lo stesso con

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