依存ルール
このドキュメントの目的
クリーンアーキテクチャの核心である依存ルールを深く理解することが目標です。なぜ内側は外側を知ってはいけないのか、その理由を明確にします。
目次
依存ルールとは
シンプルなルール
┌─────────────────────────────────────────────┐
│ 依存ルール │
├─────────────────────────────────────────────┤
│ │
│ 「ソースコードの依存は、 │
│ 常に内側(より抽象的な層)に向かう」 │
│ │
│ 言い換えると: │
│ 「内側の層は外側の層について │
│ 何も知ってはならない」 │
│ │
└─────────────────────────────────────────────┘
具体的には
┌─────────────────────────────────────────────┐
│ 許される依存 │
├─────────────────────────────────────────────┤
│ │
│ Controller → UseCase ✓ │
│ UseCase → Entity ✓ │
│ Repository実装 → Repository ✓ │
│ │
│ 外側が内側を知る = OK │
│ │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ 許されない依存 │
├─────────────────────────────────────────────┤
│ │
│ Entity → UseCase ✗ │
│ UseCase → Controller ✗ │
│ UseCase → PostgreSQL ✗ │
│ │
│ 内側が外側を知る = NG │
│ │
└─────────────────────────────────────────────┘
「知る」とは
┌─────────────────────────────────────────────┐
│ コードレベルで「知る」とは │
├─────────────────────────────────────────────┤
│ │
│ ・import文がある │
│ ・クラス名/関数名を直接使っている │
│ ・型として参照している │
│ │
│ 内側のファイルに外側のimportがあれば │
│ それは依存ルール違反 │
│ │
└──────────────────────── ─────────────────────┘
なぜこのルールが必要か
変更の波及を防ぐ
┌─────────────────────────────────────────────┐
│ 依存ルールがない場合 │
├─────────────────────────────────────────────┤
│ │
│ Entity → PostgreSQL │
│ │
│ PostgreSQLの仕様変更 │
│ ↓ 影響 │
│ Entityを修正 │
│ ↓ 影響 │
│ Entityを使う全てのUseCaseを確認 │
│ ↓ 影響 │
│ テスト全体のやり直し │
│ │
│ 技術的詳細の変更がビジネスロジックに波及 │
│ │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ 依存ルールがある場合 │
├─────────────────────────────────────────────┤
│ │
│ Entity ← PostgreSQL実装 │
│ │
│ PostgreSQLの仕様変更 │
│ ↓ 影響 │
│ PostgreSQL実装のみ修正 │
│ │
│ Entityは無傷、UseCaseも無傷 │
│ │
└─────────────────────────────────────────────┘
変わりやすさと変わりにくさ
┌────────────────────────────────── ───────────┐
│ なぜ内側を守るのか │
├─────────────────────────────────────────────┤
│ │
│ 内側(Entity、UseCase): │
│ ├── ビジネスの本質 │
│ ├── 変わりにくい │
│ └── 変わると影響が大きい │
│ │
│ 外側(DB、Framework): │
│ ├── 技術的な選択 │
│ ├── 変わりやすい │
│ └── 変えられるべき │
│ │
│ 変わりやすいものの変更が │
│ 変わりにくいものに影響しない構造を作る │
│ │
└─────────────────────────────────────────────┘
依存を逆転させる方法
問題: UseCaseがDBを使いたい
UseCaseはデータを永続化したい。でもDBを直接知ってはいけない。どうする?
素朴な実装(ルール違反):
UseCase
│
└── PostgreSQLRepository を直接使う
(UseCaseがPostgreSQLを知っている)