2011-01-23 16 views
23

Czy naprawdę dobrą praktyką jest unikanie używania operatora NOT w warunkach IF w celu zwiększenia czytelności kodu? Słyszałem, że if (doSomething()) jest lepszy niż if (!doSomething()).Używanie operatora NOT w warunkach IF

+2

"' if (...) jest lepsza niż '' if (...!) '" - Czekaj, wat? – delnan

+0

Pytanie zostało nieznacznie rozszerzone, aby było bardziej zrozumiałe. – Eugene

+0

Dla mnie nie jest fakt, że ktoś jest lepszy od drugiego, po prostu musisz użyć odpowiednich w każdej sytuacji, świat warunkowy jest bardzo szeroki i różnorodny. –

Odpowiedz

32

To naprawdę zależy od tego, co próbujesz osiągnąć. Jeśli nie masz jeszcze żadnej klauzuli, wtedy wydaje się, że if(!doSomething()) jest w porządku. Jednakże, jeśli masz

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

pewnie bym odwrócić tę logikę do usuwania operatora ! i sprawi, że klauzula if nieco bardziej jasne.

+0

+1 Bardzo to prawda. –

+1

Ja (prawie) zawsze strukturyfikuję, jeśli elses, aby najpowszechniejsza gałąź egzekucji była pierwsza. – Dunes

+1

Istnieje reguła PMD ConfusingTernary, aby to sprawdzić: http://pmd.sourceforge.net/pmd-5.0.3/rules/java/design.html#ConfusingTernary –

11

Nie, nie ma absolutnie nic złego w korzystaniu z operatora ! w instrukcjach if..then..else.

Najważniejsze jest nazewnictwo zmiennych oraz w twoim przykładzie metody. Jeśli używasz:

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

Jednakże:

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

To wszystko sprowadza się do czytelności. Zawsze dąż do tego, co jest najbardziej czytelne, a nie popełnisz błędu. Zawsze staraj się również zachować ciągłość kodu, na przykład spójrz na Bill the Lizards answer.

0

Nigdy wcześniej nie słyszałem o tym.

Jak

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

lepiej niż

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

Im później jest bardziej przejrzysty i zwięzły.

Oprócz! operator może pojawić się w złożonych warunkach, takich jak (! a || b). Jak więc tego uniknąć?

Użyj! operatora, kiedy potrzebujesz.

+1

nie robisz czegoś w stanie – Mikey

19

Jako ogólne stwierdzenie warto zadbać o to, aby twoje warunki były możliwie czytelne. Dla Twojego przykładu, używając! jest w porządku. Problem jest, gdy sprawy wyglądają

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

może chcesz coś zrobić jak

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

wówczas, gdy oświadczenie jest uproszczona do

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

To właśnie sprawia, że ​​kod jest bardziej czytelny. A jeśli masz do debugowania, możesz debugować zestaw var z zestawu isOk, zamiast przekopywać się przez zmienne w zakresie. Jest to również pomocne w radzeniu sobie z NPE - łamanie kodu w prostsze kawałki jest zawsze dobre.

1

Zasadniczo nie jest to zły pomysł, aby uniknąć! -operatora, jeśli masz wybór. Jednym prostym powodem jest to, że może być źródłem błędów, ponieważ można go przeoczyć. Bardziej czytelny może być: if (conditionA == false) w niektórych przypadkach. To głównie odgrywa rolę, jeśli pominiesz część inną. Jeśli mimo wszystko masz blok else, nie powinieneś używać negacji w warunku if.

wyjątkiem składających-warunkach takich jak to:

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

Tu trzeba użyć jakiegoś negacji, aby uzyskać pożądany logiki. W tym przypadku, o czym naprawdę warto pomyśleć, to nazewnictwo funkcji lub zmiennych. Spróbuj je nazwać, aby często można było z nich korzystać w prostych warunkach bez negacji.

W takim przypadku powinieneś pomyśleć o logice isNotC() i czy można ją zastąpić metodą isC(), jeśli ma to sens.

Wreszcie twój przykład ma inny problem, jeśli chodzi o czytelność, która jest jeszcze poważniejsza niż pytanie, czy użyć negacji, czy nie: Czy czytelnik kodu naprawdę wie, kiedy doSomething() zwraca true, a kiedy false? Jeśli to nieprawda, czy tak się stało? Jest to bardzo powszechny problem, który kończy się na tym, że czytelnik próbuje dowiedzieć się, co naprawdę oznaczają zwrotne wartości funkcji.

4

Ogólnie rzecz biorąc! to doskonale dobry i czytelny operator logiczny. Nie ma powodu, aby go nie używać, chyba że upraszczasz, usuwając podwójne negatywy lub stosując prawo Morgana.

!(!A) = A 

lub

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

Jako zasada, zachować podpis swojej logicznej metody powrotne mnemoników i zgodnie z konwencją. Problem ze scenariuszem proponowanym przez @hvgotcodes jest taki, że oczywiście a.b i c.d.e nie są bardzo przyjaznymi przykładami. Załóżmy, że masz klasę Flight i Seat w aplikacji do rezerwacji lotów. Wtedy warunkiem rezerwacji lotu może być coś w rodzaju:

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

Ten doskonale czytelny i zrozumiały kod. Można ponownie zdefiniować logikę boolowską dla klasy Seat i zmienić na nią warunek.

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

W ten sposób usunięcie! operatora, jeśli naprawdę cię to niepokoi, ale zobaczysz, że wszystko zależy od tego, co oznaczają twoje metody boolowskie.

1

spróbować jak to

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

Nadszedł samo

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