2011-01-23 16 views
23

IF条件でNOT演算子を使用することを避けて、コードを読みやすくすることは本当に良い方法ですか? if (doSomething())がより良いと聞きましたif (!doSomething()).IF条件でNOT演算子を使用する

+2

と同じだ - 待って、ワット? – delnan

+0

質問が少し明確になるように少し拡張されました。 – Eugene

+0

私にとっては、あるものが他のものより優れているという事実ではなく、単にあらゆる状況において適切である必要があります。条件付きの世界は非常に幅広く多様です。 –

答えて

32

これは実際に達成しようとしていることによって異なります。 else節がない場合は、if(!doSomething())が問題ありません。しかし、あなたが

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

を持っている場合、私はおそらく!オペレータを削除し、if句がもう少し明確にするためにそのロジックを逆にしたいです。

+0

+1非常に真実です。 –

+1

最も一般的な実行分岐が最初に来るように、I(ほぼ)は常にelses構造になっています。 – Dunes

+1

これをチェックするPMDルールConfusingTernaryがあります。http://pmd.sourceforge.net/pmd-5.0.3/rules/java/design.html#ConfusingTernary –

11

いいえ、if..then..elseステートメントで!オペレータを使用することは間違いありません。

変数の名前は、あなたの例では、メソッドが重要です。使用している場合:

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

しかし:

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

これは、すべての読みやすさにダウンしています。常に最も読みやすいものを目指し、間違ってはいけません。常にあなたのコードを継続的に保つようにしてください。たとえば、The the Lizardsを参照してください。answer

0

これまで私はこれまで聞いたことがありません。

方法は、後には、より明確かつ簡潔である

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

より

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

優れています。

!演算子は、(!a || b)のような複雑な条件に現れることがあります。どのようにそれを避けるのですか?

!オペレーターが必要なときに。

+1

あなたは条件の中で何かしていないよ – Mikey

19

一般的な声明として、if条件を可能な限り読みやすくすることができます。あなたの例では、!大丈夫ですか?物事はあなたが

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

ような何かをしたい場合があります

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

のように見えるとき、問題文は

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

に簡略化されている場合は、あなたのこれだけのコードが読みやすくなります。また、デバッグする必要がある場合は、スコープ内の変数を調べなくても、isOkのvarsセットをデバッグできます。また、NPEを扱う場合にも役立ちます。コードを単純なチャンクに分割すると、常に良好です。

1

選択肢がある場合は、!-operatorを避けるのは一般的には悪いことではありません。 1つの単純な理由は、エラーの原因となる可能性があることです。間接的に見逃す可能性があるからです。もっと読みやすくなるのは、if(conditionA == false)の場合があります。 else部分をスキップすると、これは主に役割を果たします。 とにかくelseブロックをお持ちの場合は、if条件で否定を使用しないでください。このような構成-条件を除き

:ここでは、所望の論理を取得するには否定のいくつかの並べ替えを使用する必要が

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

。 この場合、実際に考える価値のあることは、関数や変数の命名です。 名前を付けて、簡単な条件で否定することなく使用することができます。

この場合、isNotC()のロジックについて考える必要があり、それが理にかなっていればisC()メソッドに置き換えることができます。

最終的には、否定を使用するかどうかという問題よりも読みやすさに重大な問題があります。doSomething()がtrueを返し、falseを返したとき、コードの読者が本当に知っていますか? もしそれが間違っていたら、とにかくやりましたか?これは非常に一般的な問題であり、読者が関数の戻り値が本当に意味するものを見つけることで終わります。

4

一般に、!完全に良好で読みやすいブール論理演算子です。あなたがダブルネガを取り除くかモーガンの法律を適用することによって単純化しない限り、それを使用しない理由はありません。経験則として

!(!A) = A 

または

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

、ニーモニックや慣習に沿ってあなたのboolean型の戻りメソッドのシグネチャを保ちます。 @hvgotcodesが提案しているシナリオの問題は、もちろんa.bとc.d.eがあまりにもフレンドリーな例ではないことです。フライト予約アプリケーション用のFlightクラスとSeatクラスがあるとします。飛行機予約の条件は完全に何かのようになる可能性があります。

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

これは完全に読みやすく理解できるコードです。あなたはSeatクラスのブール論理を再定義して、これに条件を書き換えることができます。

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

このように!演算子は本当にあなたを悩ませていますが、それはあなたのブールメソッドが何を意味するかによって異なります。

1

すると、この

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

のようにしてみてください "(...)` ``場合よりも優れている場合には、 `(...!)" それは

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