神クラス — 1つのクラスが何でも知っている
「とりあえずここに書く」を続けた先にできる数千行の巨大クラスが、なぜ変更を怖くしテストを不可能にするのかが分かる。責務で割るリファクタリングの初手まで。
- 神クラス(God Object)は、アプリの多くの責務とデータを1つに抱え込んだ巨大クラス。UtilManagerやServiceのような曖昧な名前で、数千行に膨らむ。
- あらゆる機能がそこに依存するため、小さな変更が全体に波及し、単体テストも切り出せない。1人しか触れない聖域になり、変更が滞る。
- 直し方は責務での分割。凝集した塊を見つけて別クラスへ切り出し、委譲でつなぐ。単一責任の原則(1つのクラスが変わる理由は1つ)が指針。
UserManager、AppService、Helper——名前からして何でも入りそうなクラスが、気づけば3000行。新機能のたびに「とりあえずここに足す」を繰り返した結果できあがるのが神クラスです。
横にスクロール
症状:どう気づくか
- 1つのクラスが数千行あり、メソッドが数十個ある。
- 名前が
Manager/Service/Util/Helperなど何でも入りそうな抽象語。 - そのファイルを開くとコンフリクトが頻発する(全員が触るため)。
- 「この機能どこ?」と聞くと、答えがいつも同じクラス。
なぜ悪いのか
神クラスは、本来別々であるべき責務とデータを1箇所に握り込みます。すると2つの形で開発が止まります。
第一に、変更が波及する。表示のための小さな修正が、同じクラスに同居する課金や認証のロジックに影響しうる。だから誰もが変更を怖がり、レビューも重くなる。
第二に、テストできない。神クラスをインスタンス化するだけで、DB・外部API・設定・他サービスがぞろぞろ必要になる。一部の振る舞いだけを切り出して検証することができず、結局テストが書かれません。
「1つのクラスが変更される理由は、1つであるべき」。言い換えると、異なる理由で変わるものは、別のクラスに分ける。課金ルールが変わるのと、表示形式が変わるのは別の理由。だから同じクラスに同居させない、という判断基準です。
直し方
一気に作り直すのは危険です。凝集した塊を1つずつ切り出すのが安全な道です。
- 一緒に変わるものを見つける。 同じデータを触り、同じ理由で変更されるメソッド群は、1つの責務の候補。
- 新しいクラスへ切り出す。 その塊を別クラスに移し、神クラスからは委譲(呼び出し)でつなぐ。外から見た振る舞いは変えない。
- テストを添える。 切り出した小さなクラスにテストを書く。これが次の分割の安全網になる。
- 繰り返す。 神クラスが薄くなるまで、塊ごとに反復する。
Before: UserManager(3000行)
認証・プロフィール・課金・通知・レポート… 全部入り
After:
Authenticator … 認証だけ
ProfileService … プロフィールだけ
BillingService … 課金だけ
UserManager … 上記を束ねる薄い窓口(あるいは消滅)
逆に、1メソッドごとにクラスを作るような過剰な分割は、今度は「どこで何が起きているか追えない」状態を生みます。目安は凝集——同じ理由で変わるものは一緒に、違う理由で変わるものは別に。数の多寡でなく、変更理由で割るのが要点です。
まとめ
- 神クラスは、多くの責務とデータを抱え込んだ巨大クラス。Manager/Service/Util のような曖昧な名前が兆候。
- 害は2つ。変更が全体に波及することと、依存が多すぎてテストできないこと。結果、変更が滞る聖域になる。
- 直し方は責務ごとの切り出し。凝集した塊を別クラスへ移し委譲でつなぐ。単一責任(変わる理由は1つ)が指針。
- 分割しすぎも害。数でなく変更理由で割る。
アンチパターン図鑑の記事ガイド
神クラス — 1つのクラスが何でも知っているを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
神クラス
比較で見る軸
難易度: intermediate / カテゴリ: アンチパターン図鑑 / タグ数: 5
導入後に効く点
あらゆる機能がそこに依存するため、小さな変更が全体に波及し、単体テストも切り出せない。1人しか触れない聖域になり、変更が滞る。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- アンチパターン図鑑
- タグ数
- 5
判断チェックリスト
- 自社の用途が「神クラス / 単一責任」に近いか確認する。
- 強みである「神クラス(God Object)は、アプリの多くの責務とデータを1つに抱え込んだ巨大クラス。UtilManagerやServiceのような曖昧な名前で、数千行に膨らむ。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。