search
LoginSignup
27

More than 3 years have passed since last update.

posted at

updated at

私はswitch文が嫌い

私は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文については
コードの不吉な臭い
の中にもあげられています。
「新装版 リファクタリング 既存のコードを安全に改善する」

switchを消すメイキング的な話

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
27