[オブジェクト指向]良いコード/悪いコードで学ぶ設計入門 6章 switch文の重複とクラスの肥大化

mino6_2プログラミング

どうも。つじけ(tsujikenzo)です。このシリーズでは、2022年5月に発売されました書籍「良いコード/悪いコードで学ぶ設計入門」についてお送りします。今日は2回目です。

前回のおさらい

前回は、「この書籍と6章について」をお送りしました。

[オブジェクト指向]良いコード/悪いコードで学ぶ設計入門 はじめに
どうも。つじけ(tsujikenzo)です。このシリーズでは、2022年5月に発売されました書籍「良いコード/悪いコードで学ぶ設計入門」についてお送りします。今日は1回目です。章立ては順不同になりますが、ご了承ください。書...

今回は、「switch文の重複とクラスの肥大化」をお届けします。

今日のアジェンダ

  • switch文
  • クラスの肥大化

switch文

switch文は、実行されると、条件式の値を求め、statements文を処理します。

switch(条件式){
    statements
}

statements文では、まずcaseラベルを探して、caseラベルに付与されている値を同一演算子(JavaScriptでは===)で判定します。

一致するラベルがあれば、そのcaseラベルの後ろに続く最初の文からコードブロックを実行します。

つまり、case2のラベル値が一致したばあいは、コードブロック#2とコードブロック#3が実行されます。

switch(条件式){
    case1:
    //コードブロック#1を実行する
    case2:
    //コードブロック#2を実行する
    case3:
    //コードブロック#3を実行する     
}

なので、case節には、かならずbreak文を記述し、switch文を抜ける処理を行います。(break文を書かない、フォールスルーというテクニックもあります)

switch(条件式){
    case1:
    //コードブロック#1を実行する
    break;
    case2:
    //コードブロック#2を実行する
    break;
    case3:
    //コードブロック#3を実行する
    break;      
}

これは、else if文による条件式のネストを、早期returnさせることと、考え方は同じです。

switch文の重複

switch文は、以下の2つの要素の組み合わせを行うときに使います。

項目場所
複数の判定要素条件式曜日、担当者、顧客コード
複数の処理コードブロック担当を決める、金額を決める

そして、複数人で開発をおこなうときや、あとから機能を追加するときに、switch文が重複してしまうことがあります。

function myFunction() {

  //曜日判定を行い、掃除当番を決める
  switch (曜日) {
    case 月:
      //担当つじさん
    break;
    case 火:
      //担当たかはし(たいと)さん
    break;
    case 水:
      //担当たかはし(のりあき)さん
    break;
    //以降略
  }

  //中略(数カ月後に機能追加)
  //曜日判定を行い、掃除の時間を決める
  switch (曜日) {
    case 月:
      //朝のみ
    break;
    case 火:
      //昼・夕方
    break;
    case 水:
      //昼のみ
    break;
    //以降略
  }
}

switch文が重複すると、たとえば曜日判定を月~金で行っていたら、土曜日を追加したときに、修正が大変です。

なので、switch文の重複を解消するには、単一責任選択の原則を取り入れます。

これは、クラスや関数などのモジュールの責任を単一にすると、変更するときに影響範囲がわかりやすいということです。

switch文を1つにまとめて重複を解消する

書籍のリスト6.18を動くところまで記述すると、以下のようなコードになります。(一部のコードを省略しています)

minodriven-goodcodebadcode/Section6/Sample6_18.java at main · tsujike/minodriven-goodcodebadcode
ミノ駆動本のソースコードです。. Contribute to tsujike/minodriven-goodcodebadcode development by creating an account on GitHub.

JavaScriptでも書いてみましょう。

minodriven-goodcodebadcode/Section6/myFunction6_3.js at main · tsujike/minodriven-goodcodebadcode
ミノ駆動本のソースコードです。. Contribute to tsujike/minodriven-goodcodebadcode development by creating an account on GitHub.

糖衣構文ってすごいですね。

クラスの肥大化

単一責任選択の原則を摘要すると、処理を1か所にまとめることができました。

しかし、切り替えたい条件分岐が増えるごとに、モジュール(クラス)は肥大化します。

肥大化すると、どんな弊害があるのか、たとえ話をしてみます。

新しい土地を開拓しよう

神様に、とある土地を複数与えられるとします。しかし、1つの土地にしか住めません。

わたし的には、面積がもっとも広い土地にコスパよく住みたいので、与えられた土地の面積を、毎回計算するとします。

これを、switch文で書くと、土地の形を条件式で判定し、面積を求める(底辺 x 高さなど)と思います。 

そして、一番重要なことは、一番広い土地が見つかったら、お金はいくら必要なのかなど、さまざまな計算をして判断することです。

  • 住む家の広さを決める
  • 住める人数を割り出す
  • 必要なお金を計算する

このプログラム全体では、条件式で分岐した「土地の形によって計算式が違うこと」は、さほど重要な価値を提供していません

表に出さず、プログラムの裏側でいい感じに処理してくれればかまいません。 

プログラムの安定と不安定

分岐のあるような条件式を、ソースコードの表に出さないもうひとつの理由は、条件式の分岐がプログラムの中で不安定な要素だからです。

不安定な要素は、プログラムをどんどん肥大化させて、読みづらくメンテナンスのできないプログラムを産んでしまいます。 

条件式の分岐を表に出さないテクニックがあるので、次回ご紹介します。

まとめ

以上で、「switch文の重複とクラスの肥大化」をお送りしました。

概念的な話が増えてきました。もう少し上手に言語化できないか、模索中です。

次回は、「インターフェイス」 をお届けします。

参考資料

このシリーズの目次

タイトルとURLをコピーしました