メインコンテンツまでスキップ

分岐ロジックの肥大化

説明(どんな問題か)

どんな状態か?

  • if / else if / switch による条件分岐が多すぎてコードが読みにくい
  • 処理の追加・変更のたびに、同じ分岐ロジックを複数箇所に書く
  • 条件が増えると、バグの温床になりやすく、保守性も低下

なぜ問題か?

  • 修正時に全ての条件を確認する必要がある
  • 1 つの関数・クラスに責任が集中する
  • ユニットテストが困難(条件によって異なる処理が密結合)
  • 拡張がしにくい(開閉原則に反する)

アンチパターンのコード例

function calculatePrice(userType: string, basePrice: number): number {
if (userType === "student") {
return basePrice * 0.8;
} else if (userType === "member") {
return basePrice * 0.9;
} else if (userType === "vip") {
return basePrice * 0.7;
} else {
return basePrice;
}
}

問題点:

  • if/else が増え続けると、可読性・テスト性・エラー発生リスクが高まる
  • 新しい userType を追加するたびに関数本体を修正する必要があり、安全に拡張できない
  • 割引の計算が直接埋め込まれていて、他の場所で使い回しにくく、一元管理が困難

パターン別のリファクタリング

対応可能なデザインパターン例

パターン概要主な解決アプローチ
Strategy条件に応じた処理を外部に切り出す実行時に処理を差し替える柔軟性
State状態と処理を 1 対 1 で対応条件を「状態オブジェクト」に任せる
Command条件ごとの命令をオブジェクト化実行・取り消しなど操作の記録にも ◎
Chain of Responsibility条件判定を責任の連鎖で処理条件分岐をフローで自然に表現できる
Interpreter文法に従ったルールや式を解釈・評価複雑な条件ロジックを構文として分離し、拡張可能にする