判断ガイド: クラスを分けるべきか¶
判断フロー¶
Q1. そのクラスの「変更理由」(誰のどんな都合で変わるか)を列挙せよ
→ 1つしかない ──> 分けない(行数が多くても分けない)
→ 2つ以上ある ──> Q2へ
Q2. その複数の理由で、実際に変更が起きているか?(履歴・直近の予定)
→ 起きていない(理屈上の分類だけ)──> 保留(分割候補としてメモのみ)
→ 起きている ──> Q3へ
Q3. 分けた後の2つは、独立して変更・テストできるか?
→ できる ──> 分ける(1責務ずつ、段階的に)
→ 密結合のまま(常に両方一緒に変更される)──> 分け方が間違い。境界を引き直す
判断材料¶
- 分けるシグナル: 変更履歴に別種の理由が混在/UI・保存・通信の都合がロジックに混入/テストのセットアップが巨大/「このクラスのこの辺だけ触る」という会話が頻発
- 分けないシグナル: 変更理由が1つ(数学ベクトル、純アルゴリズム)/一緒にしか変更されない/分けるとgetter/setterの橋だらけになる
例外¶
- 行数だけを理由に分けない: 3000行でも変更理由が1つなら(稀だが)分割は不要。逆に200行でも理由が3つなら分ける
- プロトタイプ・ジャム: 分けない。捨てるコードに分割投資は無意味
- チーム分担の都合: 責務が1つでも「2人が同時に触ってコンフリクトする」なら物理分割(ファイル分割)の価値はある——設計上の分割とファイル分割は別の判断
トレードオフ¶
- 得: 変更の局所化、テスト容易性、並行作業
- 失: クラス間の受け渡しコード、追跡の手数(1画面で読めなくなる)、分けすぎるとショットガン手術(1変更で多ファイル修正)——分割の失敗は「大きすぎ」と「細かすぎ」の両方向にある
実践のコツ¶
- 分割は1責務ずつ・動かしたまま(リファクタリングの手順: 抽出→委譲で旧API維持→呼び出し側移行→旧API削除)
- 最初の一手は「クラス分割」ではなく関数の抽出でよいことが多い(SRPの単位はクラスとは限らない → SRPの自由関数の例)
理解度チェック¶
- 分割の判断基準が「行数」ではない理由を説明できますか。
- 「分け方が間違っている」ことを示すQ3のシグナルは?
- 設計上の分割とファイル分割が別の判断である例は?
前: カテゴリ目次 | 次: インターフェースを作るべきか