クリーンアーキテクチャ
ビジネスロジックを外部の技術的詳細から分離し、依存関係を内側に向けることで変更に強い設計を実現するアーキテクチャ原則
クリーンアーキテクチャとは
クリーンアーキテクチャは、Robert C. Martin (Uncle Bob) が 2012 年に提唱したソフトウェア設計の原則である。同心円状のレイヤー構造を持ち、最も内側にビジネスルール (エンティティ、ユースケース) を配置し、外側にフレームワーク、データベース、UI などの技術的詳細を配置する。
核心となるルールは「依存関係は常に内側に向かう」ことだ。内側のレイヤーは外側のレイヤーについて何も知らない。これにより、データベースを PostgreSQL から DynamoDB に変更しても、ビジネスロジックには一切影響しない設計が実現する。
レイヤー構造
内側から外側に向かって 4 つのレイヤーで構成される。
- Entities (エンティティ): ビジネスルールの核心。アプリケーション固有ではなく、企業全体で共通するルール
- Use Cases (ユースケース): アプリケーション固有のビジネスルール。エンティティを操作してビジネス目的を達成する
- Interface Adapters (インターフェースアダプター): ユースケースと外部の間のデータ変換。Controller、Presenter、Gateway が該当
- Frameworks & Drivers (フレームワーク): Web フレームワーク、データベース、UI など。最も外側で、最も変更されやすい
依存性逆転の原則 (DIP) との関係
内側のレイヤーが外側に依存しないためには、依存性逆転の原則が不可欠だ。ユースケース層がデータベースにアクセスする場合、ユースケース層にインターフェース (Repository) を定義し、外側のレイヤーがそのインターフェースを実装する。
// ユースケース層 (内側) - インターフェースを定義
interface OrderRepository {
findById(id: string): Promise<Order | null>;
save(order: Order): Promise<void>;
}
// インフラ層 (外側) - インターフェースを実装
class DynamoDBOrderRepository implements OrderRepository {
async findById(id: string): Promise<Order | null> { /* DynamoDB 固有の実装 */ }
async save(order: Order): Promise<void> { /* DynamoDB 固有の実装 */ }
}
類似アーキテクチャとの比較
| アーキテクチャ | 提唱者 | 特徴 |
|---|---|---|
| クリーンアーキテクチャ | Robert C. Martin | 同心円モデル、依存関係ルール |
| ヘキサゴナルアーキテクチャ | Alistair Cockburn | ポートとアダプター、外部との接続点を明示 |
| オニオンアーキテクチャ | Jeffrey Palermo | ドメインモデルを中心に据えた層構造 |
これらは本質的に同じ原則 (ビジネスロジックの独立性) を異なる視点で表現したものであり、実装上の違いは小さい。
実務での適用判断
大規模な業務システムやエンタープライズアプリケーションで威力を発揮する。特に、長期間にわたって保守・拡張が必要なプロジェクトに適している。
一方、小規模なプロジェクトや短命なプロトタイプに過度に適用すると、レイヤー間のインターフェース定義やデータ変換のボイラープレートが増え、開発速度が低下する。プロジェクトの規模と寿命に応じて、適用の度合いを調整する判断が重要だ。CRUD 中心の単純なアプリケーションでは、フレームワークの規約に従うシンプルな構成の方が生産性が高い。
「Clean Architecture - 達人に学ぶソフトウェアの構造と設計」(Robert C. Martin 著) が原典であり、SOLID 原則やコンポーネント設計の原則と合わせて体系的に解説されている。
現場での応用を知るには関連書籍も役立つ。