純粋な OO コードでスイッチを使用すると、コードの匂いがします。これは、それらの定義が間違っているという意味ではなく、使用についてよく考える必要があるということです。特に注意してください。
ここでの switch の定義には、switch ステートメントとして簡単に書き直すことができる if-then-else ステートメントも含まれます。
スイッチは、操作対象のデータに近い動作を定義していないこと、たとえばサブタイプのポリモーフィズムを利用していないことを示している可能性があります。
オブジェクト指向言語を使用する場合、オブジェクト指向の方法でプログラミングする必要はありません。したがって、より関数型またはオブジェクトベースのプログラミング スタイルを使用することを選択した場合 (たとえば、よりリッチなドメイン モデルとは対照的に、データのみを含み動作を含まない DTO を使用する場合)、スイッチを使用しても問題はありません。
最後に、オブジェクト指向プログラムを作成するとき、スイッチはオブジェクト指向モデルの「エッジ」で非常に便利です。オブジェクト指向以外の外部の世界からオブジェクト指向モデルに何かが入り、この外部エンティティをオブジェクト指向概念に変換する必要がある場合です。できるだけ早くこれを行うのが最善です。たとえば、データベースの int は、スイッチを使用してオブジェクトに変換できます。
int dbValue = ...;
switch (dbValue)
{
case 0: return new DogBehaviour();
case 1: return new CatBehaviour();
...
default: throw new IllegalArgumentException("cannot convert into behaviour:" + dbValue);
}
いくつかの応答を読んだ後に編集します。
Customer.isInvestable
: 素晴らしい、ポリモーフィズム。しかし、今はこのロジックを顧客に関連付けており、さまざまな動作を実装するためだけに、顧客のタイプごとにサブクラスが必要です。前回チェックしたとき、これは継承の使用方法ではありません。顧客のタイプを のプロパティにCustomer
するか、顧客のタイプを決定できる関数を持たせる必要があります。
二重ディスパッチ: ポリモーフィズムが 2 回。しかし、あなたの訪問者クラスは本質的に大きなスイッチであり、上で説明したのと同じ問題がいくつかあります。
さらに、OPの例に従って、ポリモーフィズムはCustomer
それ自体ではなく、顧客のカテゴリにある必要があります。
値の切り替えは問題ありません: わかりましたが、範囲やよりエキゾチックな条件をテストできる if-then-else とは対照的に、ほとんどの場合、switch ステートメントは単一int
の , char
, , ... 値をテストするために使用されます。enum
しかし、この単一の値でディスパッチし、上記で説明したようにオブジェクト指向モデルの端にない場合、スイッチは値ではなく型でディスパッチするためによく使用されるようです。または: if -then-else の条件付きロジックをスイッチで置き換えることができない場合は、おそらく大丈夫ですが、そうでない場合はおそらくそうではありません。したがって、OOP のスイッチはコードの匂いだと思います。
型をオンにするのは OOP スタイルではありませんが、値をオンにするのは問題ありません。
自体は単純化しすぎています。
出発点に戻ると、 aswitch
は悪くありません。常に非常に OO であるとは限りません。問題を解決するために OO を使用する必要はありません。OOP を使用する場合は、スイッチに特に注意する必要があります。