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

責務の集中

説明(どんな問題か)

どんな状態か?

  • 1 つのクラスやモジュールが過剰な責任を持ちすぎている
  • あらゆる処理がそのクラスの中にあり、変更や拡張時に全体に影響が及ぶ
  • データ保持、処理実行、状態管理など全部入り

なぜ問題か?

  • クラスの目的が曖昧になり、読みづらく変更が怖いコードになる
  • テストが困難(多くの依存や前提を持つ)
  • 再利用不可・責務分離失敗 → スパゲッティ化の温床

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

// Godクラス:責務が全部入り
class OrderManager {
private orders: string[] = [];
private userEmail: string = "";
private discountType: string = "none";

setUser(email: string) {
this.userEmail = email;
}

addOrder(productId: string) {
this.orders.push(productId);
}

applyDiscount(type: string) {
this.discountType = type;
}

calculateTotal(): number {
let basePrice = this.orders.length * 1000;
if (this.discountType === "student") {
return basePrice * 0.8;
} else if (this.discountType === "member") {
return basePrice * 0.9;
}
return basePrice;
}

confirmOrder() {
// 1. 在庫調整
console.log("在庫を減らす");

// 2. メール通知
console.log(`メールを ${this.userEmail} に送信`);

// 3. ログ出力
console.log("注文完了ログ");
}
}

問題点

  • 注文データ管理・割引ロジック・通知処理・ログ記録すべてが同一クラスにある
  • 「何をしてるクラスなのか」が曖昧
  • 修正が波及しやすく、テスト不能な巨大クラスに成長しがち

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

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

パターン概要主な解決アプローチ
Facade共通 API を作って内部の複雑さを隠す複数機能を外部から簡潔に呼び出せるようにする
Strategy振る舞い(戦略)を差し替え可能にする拡張しやすく、テストしやすい設計にする
State状態ごとの処理を分離する条件分岐の代わりに状態クラスで処理
Compositeツリー構造に整理し「個」と「集合」を統一的に扱う階層構造の責務を整理して、責任範囲を明確に
Iterator内部構造の走査方法を抽象化走査処理の統一とカプセル化によって、保守性向上