私はswitch文が嫌いである。
###理由1:同じ変数が入るswitch文があちこちにある場合には問題が多い。
同じ変数が入るswitch文が多数ある場合には、「単一責任の原理」を破っている可能性が高い。コードを改変したとき、一方だけ改変して、他方が放置される可能性が生じる。
###理由2:論理構造とデータが分離されていない。
switch文では、データが追加されるとcaseの分岐が増えてしまい、制御構造への変更が生じてしまう。データの追加によって制御構造が変わってしまうのは、case文がbreakを書き忘れしうることから、うれしくない。
###理由3:整数型しか用いることができない。
switch文で記述できるのは、整数値に限られる。そのため、比較先の値がenum型を使われることが多いのだが、enum型の値は、印字したときに整数値にすぎず(注)、「5という値は何を意味していたかなあ」とヘッダファイルからenumの値とその意味を探らなければならなくなる。
整数型で値の比較で条件わけするのは、確かに速いのだろう。しかし、CPUの性能が上がっているときには文字列との比較をして、文字列を印字させた方が、はるかに意味がわかりやすく、開発時の値の表示の意味がわかりやすい分だけ、開発効率が上昇するように思う。
###理由4:switch文ではbreak;のありなしの自由度があるのが嫌い。
分岐の数が多数あるときに、いちいちswitch-caseの詳細をきちんと読むことをしたくない。どのcaseではbreakがあり、どのcaseにはbreakがないなどの可能性がありのが嫌い。
###理由5:caseごとに、記述される動作が共通性なく記述できることが嫌い。
caseごとに記述できる内容は、脈絡なくどのような内容でも記述可能です。そのため、そのswitch文が何をするのかは、全てを読まないと確認できないのです。
switch(dayOfWeek){
case Sunday:
市場に出かけ;
break;
case Monday:
おふろをたいて;
break;
case Tuesday:
おふろにはいり;
break;
case Wednesday:
ともだちが来て;
break;
case Thursday:
送っていった;
break;
case Friday:
糸まきもせず;
break;
case Saturday:
おしゃべりばかり:
break
default:
;
}
##対策:
私は、このような目的にmap型を使っている。
効果1:
switch文をstd::map型に置き換えることで、そのmap型を参照することで、map型の定義を1回記述するだけで済むので、単一責務の原則を実現しやすい。
効果2:
論理構造とデータが分離される。データの追加があっても、論理構造が改変されることがない。
効果3:
std::mapなどのように条件わけの入力にstd::stringや他のデータ構造を入れることができる。
そのため、enum型よりも表示させたときに意味がわかりやすい。
効果4:
map型は値の入力に対して値を返すだけなので、breakの有り無しのような自由度が入りようがない。
効果5:
map型は返される値の型が決まっているので、一定のルールが守られる。
返される値に関数を入れることもできるので、一貫性のある設計を簡潔に記述することができる。
注:
ブログサイトenum(列挙型) の使い方
C++ では、enum(列挙型) の値を例えば printf で表示しようとすると、整数として表示するしか方法がないということです。
追記:
switch文については
[コードの不吉な臭い]
(http://qiita.com/NagaokaKenichi/items/22972e6ba698c7f2978a#10-switch%E6%96%87)
の中にもあげられています。
「新装版 リファクタリング 既存のコードを安全に改善する」