2010-12-02 7 views
11

コードの可読性とは別に、ifステートメントをたくさん使用することは悪いのはなぜですか?多くのifステートメントを使用する際の短所

+0

ほとんどのプログラムには、多くのif文があります。私はこれが悪いとは聞いたことがありません。 *深くネストされた* if文をおそらく参照していますか? –

+1

私は知らないのですか?どんな状況で? –

+0

1つの問題は、多くのコードパスを導入していることです。これにより、コードをテストすることが困難になります。各パスを個別にトリガーするのは難しいかもしれません。言及された戦略のような使用可能なデザインパターンを見つける方が良い。そうすれば、個々のコードパスをもっと簡単にテストすることができます。 –

答えて

11

多くのif文が1つずつある場合は、switch case文がより便利です。少なくとも、すべてのifステートメントを実行する必要はないため、応答時間が固定されている可能性があります。

文は通常

A)Violation of Single responsibility Principle

b)が時々あるため、プロセッサアーキテクチャのStrategy Design Pattern

+5

'switch'文は、必ずしも(少なくともC#ではなく)一定の応答時間を持つとは限りません。しかし、このような超小型最適化の心配は、皆さんにとっては時間の無駄です。 – LukeH

+2

@LukeH:私は実際に昨日の大半を、アプリでブランチペナルティを追跡し、それらを削除するかブランチレスアルゴリズムで置き換えて、250msのヒッチを50msまでノックダウンしました。 – Crashworks

+0

@クラッシュワークス:だからこそ、私は、ただの毛布* "みんな"ではなく、 "ほんとうのみんな" *と言ったのです。私はあなたがルールを証明する例外の1つであると考えています。 – LukeH

0
if(A) 
{ 
}else 
if(B) 
{ 
}else 
if(C) 
{ 
}else 
if(D) 
{ 
}else 
{ } 

すべてif sが、まだそれを "O(N)" のようなものを作る "計算された" 取得する必要があります。可能であれば避けてくださいswitch(Lalala)

+1

'else'を使用していて、一致する条件が評価されなかった後に' if'を残している場合。 'if'がマッチせず、最後の' else'が実行された場合にのみ悪化します。 – TheVillageIdiot

+0

@TheVillage、はい、これは私が言及しているものです。スイッチのデフォルト:case。例えば。 Cが一致条件であれば、AとBはまだ評価されなければならない。スイッチで私たちはCにまっすぐに飛び乗ることができた。 – Muggen

+0

@Henk、すみません、ただの学生です。 – Muggen

1

に出てリファクタリングする必要が示している場合(および他)の多くは、それが見つけるために、より効率的です分岐を避ける方法。これはifステートメントの欠点と考えられます。

0

もう1つの可能性は、if文が何をしているかによって異なります。場合によっては、適切に設計されたクラス階層によってより良い判断を下すことができます。

あなたが言ったifステートメントのいくつかの例を投稿できますか?

13

すべてのif/elseを書くと、テストする必要があるコードパスの数が増えます。

0

ifステートメントがパイプラインでストールを生成する可能性があります。パイプラインの危険性hereについて読むことができます。したがって、非常に重要なアプリケーションの場合、大きなループで多くのifステートメントを使用することはお勧めできません。最新のプロセッサーでの分岐予測やさまざまなif条件のベンチマークについての記事もthisにチェックしてください。

また、ケースステートメントについて多くの人が話しています。 this SOスレッドを確認してください。

最終的にパイプラインについてはwiki articleはすべてのプログラマーが読んでいるはずです。

希望します。

1

Chusdadが正しいです。スイッチの構造は複数のif-elseより優れています。次のアプローチは、enumをスイッチキーとして使用する方法です。この場合、スイッチのenum要素の1つについて言及するのを忘れた場合、警告が表示されます。

しかし、enumとスイッチを使用している場合は、より良い設計のために進んでください:スイッチをすべて削除してください!

あなたの列挙型で抽象的なビジネスメソッドを宣言してください。それぞれのenum要素に対して実装します。スイッチを実装する代わりにenumElement.theMethod()を呼び出します。

ここは例です。ここで

enum Foo { 
    ONE { 
     public void foo() { 
      // do something 
     } 
    }, 

    TWO { 
     public void foo() { 
      // do something 
     } 
    }, 

    ; 
    public abstract void foo(); 
} 

はこれを使用するコードです:

Foo.valueOf(System.getProperty("foo")).foo(); 

は、次のと、この行の比較:

String foo = System.getProperty("foo"); 
    if("ONE".equals(foo)) { 
     //..... 
    } else if("ONE".equals(foo)) { 
     //..... 
    } else { 
     //..... 
    } 

私はコメントは必要ありませんと思います。

3

私が尋ねなければならない質問は、「何に反対」ですか?

switch文とは対照的に、可読性とは対照的に、時にはが効率的になります。 (特定の数のブランチよりも確かにC#では確かに他のもののように)コンパイル時に一連のifステートメントに変わりますが、その番号を超えてハッシュベースのルックアップとジャンプに変わります平均的な場合にはより高速になる可能性があります。

また、異なるケースの相対頻度についてよく知っている場合は、ifステートメントのセットで効率を上げることができます。例えば。 95%のケースが最初のブランチにマッチし、4%が2番目のマッチにマッチし、1%が残りのマッチにマッチすれば、これは単一の比較を行い、場合によっては分岐しなくても95%のケースでより良いパフォーマンスを得ることができます。

So. おそらくこの場合、効率が向上します。

まだ、多くの地獄の可読性は数えます。極端な例として、Turing-complete言語のコンパイラがどれくらい小さいかを見るために設計されたTuring-complete言語があります。そのデザイナーは "brainf ** k"という名前のデザイナーです。これは実際のプログラミングでの可読コードの重要性についての素晴らしいコメントです。

多くのif文の大きな問題は、クラス階層を使ってモデル化できるif文を使って何かをモデリングしていることを示すことが多いということです。ある意味では、これは読みやすさのもう一つの取り組みです(プログラムがどちらかといえばうまくいくと仮定します)。しかし、それはプログラム全体の可読性と分かりやすさに関するものです。それはあなたがプログラムのメンタルモデルに大いに影響を与え、拡張性と影響力は、あなたがそれをいかにうまく維持できるかだけでなく、できるだけそれを考えます。それは、誰かがそれを取り除く方法を学ぶまでは、従来のタイムシンクになるプログラムと、投資収益を引き続き提供するプログラムとの違いになります。

0

if文を同じ条件で何度も繰り返し書いていると、そのタイプ階層のその部分を作るのがより保守的になります。

この条件のロジックが変更された場合は、それを使用して変更するステートメントをすべて削除する必要があります。

ロジックがクラス階層にカプセル化されている場合は、一度変更する必要があります。

関連する問題