CTS-KB

クリーンアーキテクチャ

くりーんあーきてくちゃ

Clean Architecture クリーンアーキテクチャパターン
#アーキテクチャ #設計パターン #DDD

依存方向を「外側 → 内側」に固定し、ビジネスルール(ドメイン層)をフレームワーク・DB・UI から守るアーキテクチャ。Robert C. Martin(Uncle Bob)が 2012 年のブログ記事で整理し、後に同名書籍(2017)で体系化した。

概要

クリーンアーキテクチャは新発明ではなく、 ヘキサゴナルアーキテクチャオニオンアーキテクチャ・DCI など先行する複数の整理を統合し、依存方向のルールを明文化したもの。同心円の図で表現されることが多い。

4 つの同心円

            ┌──────────────────────────────────┐
            │  Frameworks & Drivers            │
            │  (Web / DB / 外部 API / UI)      │
            │  ┌────────────────────────────┐  │
            │  │ Interface Adapters         │  │
            │  │ (Controller / Presenter / │  │
            │  │   Gateway)                │  │
            │  │  ┌──────────────────────┐  │  │
            │  │  │ Use Cases            │  │  │
            │  │  │  (アプリ固有の業務) │  │  │
            │  │  │  ┌────────────────┐  │  │  │
            │  │  │  │ Entities       │  │  │  │
            │  │  │  │ (企業横断の   │  │  │  │
            │  │  │  │   業務ルール) │  │  │  │
            │  │  │  └────────────────┘  │  │  │
            │  │  └──────────────────────┘  │  │
            │  └────────────────────────────┘  │
            └──────────────────────────────────┘
責務
Entities企業横断で再利用できる業務ルールMoney, Account
Use Casesアプリケーション固有のユースケースPlaceOrderInteractor
Interface Adapters外と内のデータ変換Controller / Presenter / Gateway
Frameworks & Driversフレームワーク・I/O 技術Web フレームワーク / ORM / DB ドライバ

依存性のルール

唯一にして最重要のルール: ソースコードの依存方向は 常に外から内へ。内側のレイヤは外側の名前を一切知らない。

良い例悪い例
Entity が interface UserRepository を定義し、外側が実装Entity が import org.springframework...
Use Case が抽象 OrderRepository を呼ぶUse Case が EntityManager.persist() を直呼び
Controller が Use Case を呼び、結果を Presenter で表示Controller がドメインルールを直接持つ

入力と出力の分離

クリーンアーキテクチャは Use Case の入出力を Input Boundary / Output Boundary という別インターフェースで切り出す。これにより、UI 層(Presenter)が Use Case の内部に依存せず、テスト時のモック差し替えが容易になる。

ヘキサゴナル / オニオンとの関係

名称提唱者強調点
ヘキサゴナルAlistair Cockburn (2005)ポートとアダプタの対称性
オニオンJeffrey Palermo (2008)同心円のレイヤ構造
クリーンRobert C. Martin (2012)依存方向のルールを明文化

3 者は本質的に同型。「ドメインを中心に、外側が内側に依存する」原則を別の図と語彙で説明したもの。新規プロジェクトで「どれを採用するか」より「依存方向を内向きに固定する」ことの方が重要。

アンチパターン

  • クリーン教の儀式化 — 4 層全部に DTO を作って Mapper を増やすだけで価値が出ない
  • Entity が貧弱 — Use Case にロジックが集まり、Entity が単なるデータバッグになる
  • 層を跨ぐショートカット — Controller から直接 Repository を呼んで Use Case を飛ばす

関連記事

関連用語