アーキテクチャパターンとDDDの関係
DDDの中核原則は「ドメインモデルをシステムの中心に据える」ことです。 しかし、Evansの原典ではアーキテクチャの具体的な実装について詳しく述べられていません。 その後、複数のアーキテクチャパターンがDDDと組み合わせて提唱され、 「ドメインを外部関心事から隔離する」方法が洗練されてきました。
本章では、レイヤードアーキテクチャからクリーンアーキテクチャまでの進化を辿り、 DDDとの相性、それぞれの長所・短所、そして実践的なディレクトリ構造を解説します。
レイヤードアーキテクチャ — DDDの古典的基盤
Eric Evansが『Domain-Driven Design』で推奨したのが4層のレイヤードアーキテクチャです。 各層は明確な責務を持ち、上位層から下位層への一方向の依存を許可します。
graph TB P[Presentation Layer\nUI・API] --> A[Application Layer\nユースケース調整] A --> D[Domain Layer\nビジネスロジック] D --> I[Infrastructure Layer\nDB・外部API・メッセージング] style P fill:#3b82f6,stroke:#1d4ed8,color:#fff style A fill:#8b5cf6,stroke:#6d28d9,color:#fff style D fill:#f97316,stroke:#ea580c,color:#fff style I fill:#6366f1,stroke:#4f46e5,color:#fff
| 層 | 責務 | 含まれるもの |
|---|---|---|
| Presentation | ユーザーとの入出力 | コントローラ、ビュー、APIエンドポイント |
| Application | ユースケースの調整 | アプリケーションサービス、DTO、コマンド/クエリ |
| Domain | ビジネスロジック | エンティティ、値オブジェクト、集約、ドメインサービス |
| Infrastructure | 技術的関心事 | リポジトリ実装、ORM、メッセージブローカー、外部API |
ヘキサゴナルアーキテクチャ(Ports and Adapters)
2005年にAlistair Cockburnが提唱したヘキサゴナルアーキテクチャは、 アプリケーションをポート(インターフェース)とアダプタ(実装)で外部世界と接続する設計です。 「六角形」という名称は、ポートが任意の数だけ存在し得ることを幾何学的に表現しただけで、6つに限定する意味はありません。
核心は依存の方向を反転させることです。 アプリケーション(内側)がポートを定義し、インフラ(外側)がそのポートを実装するアダプタを提供します。 これにより、ドメインはインフラに一切依存しません。
graph LR
subgraph outside_left[駆動する側 Driving]
REST[REST API\nAdapter]
CLI[CLI\nAdapter]
end
subgraph core[アプリケーション Core]
IP[入力ポート\nPort] --> APP[Application\nService]
APP --> DOM[Domain\nModel]
APP --> OP[出力ポート\nPort]
end
subgraph outside_right[駆動される側 Driven]
DB[DB\nAdapter]
MQ[Message Queue\nAdapter]
end
REST --> IP
CLI --> IP
OP --> DB
OP --> MQ
style core fill:#1e1e2e,stroke:#f97316,color:#94a3b8
style outside_left fill:#1e1e2e,stroke:#3b82f6,color:#94a3b8
style outside_right fill:#1e1e2e,stroke:#3b82f6,color:#94a3b8
style REST fill:#3b82f6,stroke:#1d4ed8,color:#fff
style CLI fill:#3b82f6,stroke:#1d4ed8,color:#fff
style IP fill:#8b5cf6,stroke:#6d28d9,color:#fff
style APP fill:#f97316,stroke:#ea580c,color:#fff
style DOM fill:#f97316,stroke:#ea580c,color:#fff
style OP fill:#8b5cf6,stroke:#6d28d9,color:#fff
style DB fill:#3b82f6,stroke:#1d4ed8,color:#fff
style MQ fill:#3b82f6,stroke:#1d4ed8,color:#fffオニオンアーキテクチャ
2008年にJeffrey Palermoが提唱したオニオンアーキテクチャは、 ヘキサゴナルの考え方を同心円状のレイヤーとして表現し直したものです。 最内層にDomain Modelを配置し、外側に向かってDomain Services、Application Services、 そして最外層にInfrastructureとUIを配置します。
重要なルールは「依存は常に内側に向かう」ことです。 外側の層は内側の層を知っていますが、内側は外側を一切知りません。 これにより、ドメインモデルが最も安定し、インフラの変更がドメインに波及しなくなります。
クリーンアーキテクチャ
2012年にRobert C. Martin(Uncle Bob)が提唱したクリーンアーキテクチャは、 ヘキサゴナルやオニオンの原則を統合し、4つの同心円で表現したものです。
| 層(内側→外側) | 役割 | DDDとの対応 |
|---|---|---|
| Entities | ビジネスルール(最も安定) | ドメインモデル(集約、エンティティ、値オブジェクト) |
| Use Cases | アプリケーション固有のロジック | アプリケーションサービス、コマンド/クエリハンドラ |
| Interface Adapters | 外部との変換 | コントローラ、プレゼンタ、ゲートウェイ |
| Frameworks & Drivers | 外部ツール・フレームワーク | DB、Web Framework、外部API |
4つのパターンの比較
| 観点 | レイヤード | ヘキサゴナル | オニオン | クリーン |
|---|---|---|---|---|
| 提唱者 | Eric Evans (2003) | Alistair Cockburn (2005) | Jeffrey Palermo (2008) | Robert C. Martin (2012) |
| 依存の方向 | 上→下(一方向) | 外→内(DIP) | 外→内(DIP) | 外→内(DIP) |
| ドメインの位置 | 中間層 | 中心 | 最内層 | 最内層(Entities) |
| インフラとの関係 | ドメインが依存 | ポート/アダプタで分離 | 最外層に配置 | 最外層に配置 |
| テスト容易性 | 中程度 | 高い | 高い | 高い |
| 学習コスト | 低い | 中程度 | 中程度 | 中〜高 |
Explicit Architecture — DDDとの統合
Herberto Gracaが提唱したExplicit Architectureは、 ヘキサゴナル・オニオン・クリーンの各パターンとDDDの戦略的・戦術的設計を 1つの実践的なフレームワークに統合したものです。
主な特徴は以下の通りです。
- コア(内側): Application LayerとDomain Layerを明確に分離
- ポート: Primary(駆動する側)とSecondary(駆動される側)に分類
- アダプタ: 各ポートに対する具体的な技術実装
- Bounded Contextごとにヘキサゴンを1つ: 戦略的設計と直接対応
推奨ディレクトリ構造
DDDとヘキサゴナルアーキテクチャを組み合わせた場合の推奨ディレクトリ構造です。 Bounded Context単位でトップレベルを分割し、各コンテキスト内でレイヤーを配置します。
src/
├── order/ # Bounded Context: 注文
│ ├── domain/ # ドメイン層
│ │ ├── model/ # 集約、エンティティ、値オブジェクト
│ │ ├── service/ # ドメインサービス
│ │ ├── event/ # ドメインイベント
│ │ └── port/ # 出力ポート(リポジトリIF等)
│ ├── application/ # アプリケーション層
│ │ ├── command/ # コマンドハンドラ
│ │ ├── query/ # クエリハンドラ
│ │ └── port/ # 入力ポート(ユースケースIF)
│ └── infrastructure/ # インフラ層
│ ├── persistence/ # リポジトリ実装
│ ├── messaging/ # メッセージング実装
│ └── web/ # コントローラ・APIルート
├── shipping/ # Bounded Context: 配送
│ ├── domain/
│ ├── application/
│ └── infrastructure/
└── shared/ # 共有カーネル
└── kernel/ 理解度チェック
ヘキサゴナルアーキテクチャ(Ports and Adapters)を提唱したのは誰ですか?
キーボード: 1〜4 で選択、Enter で回答