ヘキサゴナルアーキテクチャ
ポートとアダプターでビジネスロジックを外部依存から分離する設計パターン
アーキテクチャDDD
ヘキサゴナルアーキテクチャとは
ヘキサゴナルアーキテクチャ (Ports and Adapters) は、Alistair Cockburn が提唱した設計パターンで、ポート (インターフェース) とアダプター (実装) でビジネスロジックを外部依存から分離する。
構造
[外部] [ポート] [コア] [ポート] [外部]
HTTP Request → Input Port → ビジネスロジック → Output Port → DynamoDB
CLI → Input Port → → Output Port → SQS
Test → Input Port → → Output Port → InMemory
| 層 | 説明 | 例 |
|---|---|---|
| コア (ドメイン) | ビジネスロジック | 注文処理、バリデーション |
| Input Port | コアへの入口 | OrderService インターフェース |
| Output Port | コアからの出口 | OrderRepository インターフェース |
| Input Adapter | 外部 → コア | Lambda ハンドラ、CLI |
| Output Adapter | コア → 外部 | DynamoDB 実装、InMemory 実装 |
TypeScript での実装
// Output Port (インターフェース)
interface OrderRepository {
save(order: Order): Promise<void>;
findById(id: string): Promise<Order | null>;
}
// コア (ビジネスロジック、外部依存なし)
class OrderService {
constructor(private repo: OrderRepository) {}
async create(input: CreateOrderInput): Promise<Order> {
const order = Order.create(input);
await this.repo.save(order);
return order;
}
}
// Output Adapter: DynamoDB 実装、InMemory 実装など差し替え可能
// Input Adapter: Lambda ハンドラ、CLI など
ヘキサゴナル vs レイヤード vs クリーン
| 観点 | ヘキサゴナル | レイヤード | クリーン |
|---|---|---|---|
| 依存の方向 | 外 → 内 | 上 → 下 | 外 → 内 |
| テスト容易性 | 高い | 中 | 高い |
| 複雑さ | 中 | 低い | 高い |
メリット
最大の利点はテスト容易性だ。Output Adapter を InMemory 実装に差し替えるだけで、DB やメッセージキューなしにビジネスロジックをテストできる。また、コアがフレームワーク (Express、Lambda など) に依存しないため、実行環境の変更がコアに波及しない。DB を DynamoDB から Aurora に移行する場合も、Output Adapter を差し替えるだけでコアは無変更で済む。
ヘキサゴナルアーキテクチャについては関連書籍でも詳しく扱われている。