ヘキサゴナルアーキテクチャ

ポートとアダプターでビジネスロジックを外部依存から分離する設計パターン

アーキテクチャDDD

ヘキサゴナルアーキテクチャとは

ヘキサゴナルアーキテクチャ (Ports and Adapters) は、Alistair Cockburn が提唱した設計パターンで、ポート (インターフェース) とアダプター (実装) でビジネスロジックを外部依存から分離する。

構造

ヘキサゴナルアーキテクチャはコア (ビジネスロジック) を中心に、Input Port (外部からコアへの入口) と Output Port (コアから外部への出口) を配置する。外部の技術的詳細 (HTTP、DB、キュー) はポートを介してコアに接続するため、コアは外部に依存しない。テスト時はポートの実装をインメモリに差し替えるだけで済む。

[外部]          [ポート]        [コア]         [ポート]        [外部]
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 での実装

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 クリーン

ヘキサゴナルとレイヤード vs クリーンの違いを以下にまとめる。

観点ヘキサゴナルレイヤードクリーン
依存の方向外 → 内上 → 下外 → 内
テスト容易性高い高い
複雑さ低い高い

メリット

最大の利点はテスト容易性だ。Output Adapter を InMemory 実装に差し替えるだけで、DB やメッセージキューなしにビジネスロジックをテストできる。また、コアがフレームワーク (Express、Lambda など) に依存しないため、実行環境の変更がコアに波及しない。DB を DynamoDB から Aurora に移行する場合も、Output Adapter を差し替えるだけでコアは無変更で済む。

ヘキサゴナルアーキテクチャについては関連書籍でも詳しく扱われている。

この記事は役に立ちましたか?

関連用語

関連する記事