第6章 条件分岐 ─迷宮化した分岐処理を解きほぐす技法─
6.1 条件分岐のネストによる可読性低下
ネストが深い場合の問題
- コードの見通しが悪くなる
- どこからどこまでがその条件の処理か読み解くのが難しい
- 複雑なロジックを正しく読み解かないと重大なバグになる
- コードを読む人全てに負荷がかかる
早期リターンを用いるメリット
- ネストを浅くできる
- 条件ロジックと実行ロジックを分離できる
- メソッドのはじめに条件ロジックの確認を行い、実行できない場合は return する
- 不要な else 句を除外できることもある
- else if が多いと見通しが悪い
[NOTE]
- ガード節の考え方がもとになっている
- ロジックをすばやく理解するためには、ロジックの見通しの良さが重要
6.2 switch文の重複
問題点
- case が増えた場合に case の追加が漏れる
- 同じ条件式の新しい概念の switch が生まれた際に気付けない
- 切り替え対象の数だけメソッドが増える
- 可読性が低下し、修正漏れのリスクが高まる
[NOTE]
- 重複コードを生まないために、コミュニケーションをしっかり取る
- 複雑になりそうな箇所は、チームでしっかり議論する
対応策
単一責任選択の原則に従う
- 同じ条件式の条件分岐を一箇所にまとめる
- Class にして Constructor 内部で switch 文を用い、全ての対象を一括で切り替える
interface を用いる
- クラス分割による関心事の分離
- 機能切り替えが簡単になる
- コンパイラが未実装のメソッドを警告
Map を用いる
- switch 文を利用せず、Map (Key: enum, Value: Interface) を活用
- Strategy Pattern の利用
6.3 条件分岐の重複とネスト
Policy Pattern を用いる
- interface を用いて、類似した条件の確認ロジックの使い回しが可能
- 判定ロジックを Rule Class として定義し、可読性を向上
- 固定された Rule Set を設定できる Policy Class を活用
6.4 型チェックで分岐しないこと
- instanceof で条件分岐せず、リスコフの置換原則を遵守
- 適切な Method を作成し、型判定を避ける
[NOTE]
リスコフの置換原則: 基本型を継承型に置き換えても問題なく動作しなければならない
6.5 interface の使いこなしが中級者への第一歩
- | 初級者 | 中級以上 |
---|---|---|
分岐 | 迷わず if 文や switch 文を使う | interface 設計を試みる |
分岐ごとの処理 | ロジックをベタ書きする | クラス化を試みる |
6.6 フラグ引数
フラグ引数を使わない
- 内部ロジックを見に行かないと動作がわからない
- フラグ引数付きメソッドは複数の機能を持ち、可読性が低下
-
メソッドは単機能になるように設計する
- 機能ごとに分けて、それぞれのメソッドにふさわしい命名をする
ストラテジパターンで切り替えを実現する
- 切り替えたいロジックを Interface にする
- enum と map で切り替える
まとめ
- ネストをなくしていく
- switch の条件式を可能な限り一箇所で管理する
- interface は必要に応じて定義していく
- Interface 設計を意識する
- リスコフの置換原則を守る
- フラグ引数を減らし、名前を見てわかるようにする
方針
条件分岐の可読性を向上させ、コードの保守性を高めるために、以下の方針を採用する:
- 早期リターンを活用してネストを浅くする
- 条件分岐の重複を避け、管理を一箇所に集約する
- interface を活用し、設計段階で拡張性を考慮する
- フラグ引数を廃止し、わかりやすいメソッド名をつける
これにより、複雑な分岐処理を整理し、可読性と保守性を向上させることを目指す。