2011-10-20 16 views
4

スイッチ/ケースステートメントを避け、列挙型でこれを行うことを避けようとすると良い理由があります。次の例を考えてみましょう: (このスイッチ/ケースはすべて列挙型とcase文

switch (theEnum) 
{ 
    case MyEnum.Enum1: 
     // dosomething 
    case MyEnum.Enum2: 
     // do something 
    case MyEnum.Enum3: 
     // do something 
    default: 
     throw new Exception("Unsupported enumeration: " + theEnum.ToString()); 

}

対)コードベースに散らばっ

public Dictionary<MyEnum, StrategyBase> BuildMapper() 
{ 
    var mapper = new Dictionary<MyEnum, StrategyBase>(); 
    mapper[MyEnum.Enum1] = new Strategy1(); 
    mapper[MyEnum.Enum2] = new Strategy2(); 
    mapper[MyEnum.Enum3] = new Strategy3(); 
return mapper; 
} 

BuildMapper()[MyEnum.Enum1].DoSomething(); 

オプション2は、より多くのOOはあるが、私は他の人が考えているかと思いました私たちがこれをするかどうかに努めなければならない理由がある場合は、このアプローチを使用してください。

switch/elseのような原則は、例えばオープン・クローズに違反すると主張するかもしれません。 OOのために

+0

Cyclometricの複雑さに集中し、メソッドが常に拡張可能である必要がある場合は、オブジェクト指向のアプローチが優れています。 – Zenwalker

+0

スイッチは非常に高速に動作することに注意してください。あなたが辞書に約10以上の項目を持っていない限り、リストを歩くことは、辞書を使うよりも速くなるでしょう。 –

答えて

1

私はそれをより読みと明示的に見えるので、第一の変形が良いと思いVisitor Pattern

+2

Viserパターンを代わりに使用し、単純なスイッチ/ケースステートメントの代わりに実行可能な天気IMHOのように*理由*を詳しく説明できますか? –

+0

実際に私はこのアイデアが気に入っていますが、訪問者は余分な配管を必要とするかもしれませんが、ストラテジーは各列挙とオペレーション毎にクラスを必要とします。 ) – Andre

+0

リフレクションを使ってメソッドに自動的に二重ディスパッチを行う方法がありますが、これは動的な性質であるため、コンパイラは列挙型の変更を検出できませんが、メソッドの上に列挙型を表す属性があれば、コンパイラの助けを得るでしょう。 – Andre

0

を使用する必要があります。

1

私は常に同じ辞書セットを返すので、BuildMapperを静的(読み込み専用)にします。

なぜこれが良いのかは、物事があるものから別のものへとマッピングされるような設計をしているときに、その理由が単純であることです。このマッピングは常に静的であり、/elseまたはそれが単なるマッピングであるという意図を隠すスイッチケース。

0

私はそれがすべてあなたが達成したいものになると言います。最初のサンプルを読みやすく、コードベースを他の人と共有することが重要です。 BuilderMapperは、あるパターンに従っている場合に便利です。

0

オレンジとリンゴを比較しているようです。

スイッチは、変数といくつかの定数データの逐次比較です。 1Kケーススイッチがない限り、それは辞書よりもはるかに優れているはずです。

もちろん、ディクショナリは非常に複雑なオブジェクトよりも、スイッチのメモリ消費量がはるかに少なくなります。

最後に、Enumは宣言されたオプションに制約されませんが、 "Flags"として組み合わせることができます。この機能は、ハッシュマップを使用して使用できません。

満足ですか?

+0

あなたが言及したパフォーマンスの問題は良い点ですが、パフォーマンスはどのくらいの10マイクロ秒ですか?私は知りませんが、おそらくビジネスラインアプリケーションの99%のためにnegilable。列挙型を 'フラグ'として使用することも当てはまりますが、戦略クラス内で実際の列挙型の値を常に構成できますか? – Andre

+0

それは本当です。 (1)スイッチはケースから別のものに「ジャンプ」することで無償で作成することができ、(2)スイッチは必須のアプローチであり、ハッシュマップは機能的です。 他の手がかりはありません... –

+0

申し訳ありませんが、私はあなたに答えませんでした...列挙型の基本型は整数です。したがって、型の安全性を損なわない限り、Enumの任意のコンポジションを使用できます。 BTW Enumは価値安全ではありません! –

1

ちょうど1つか2つの場所にあれば、私はスイッチのために行くだろう。あなたが言うように、「このスイッチ/ケースがコードベース全体に分散する可能性がある」場合、2番目の解決策に進みます。

あなたの状況では、それは良いですが、維持しやすいだけではありません。この場合、パフォーマンスとメモリ消費に関する懸念事項はまったく関係ありません。まずメンテナンスを容易にし、必要に応じて最適化してください。を最適化する必要はありません。

また、この場合、可読性の損失は無関係です。第2のアプローチではほとんど時間がかかりません。