腐敗防止層

レガシーシステムと新システムの間に変換層を設け、新システムの設計を汚染から守るパターン

DDD設計パターン

腐敗防止層とは

腐敗防止層 (Anti-Corruption Layer, ACL) は、Eric Evans が DDD で提唱したパターンで、レガシーシステムと新システムの間に変換層を設け、新システムの設計をレガシーの影響から守る。

なぜ必要か

レガシーシステムと新システムを直接接続すると、レガシー側のデータモデルや命名規則が新システムに漏れ出し、設計を汚染する。ACL を間に挟むことで、新システムは自身のドメインモデルを純粋に保ったまま、レガシーとの統合を実現できる。

問題説明
レガシーのデータモデルが汚い新システムに不要なフィールドが混入
API の互換性レガシーの API 変更が新システムに波及
用語の不一致レガシーの customer と新システムの user
段階的移行一度に全て置き換えられない

ACL の構造

ACL は新システムとレガシーシステムの間に位置する変換層である。レガシー側のデータモデルを受け取り、新システムのドメインモデルに変換してから渡す。逆方向も同様に、新システムのモデルをレガシーが理解できる形式に変換する。

新システム → [ACL (変換層)] → レガシーシステム
              ↑
  レガシーのデータモデルを
  新システムのドメインモデルに変換

TypeScript での実装

TypeScript での実装のコード例を示す。

// レガシー API のレスポンス (汚いモデル)
interface LegacyOrder {
  ord_id: string;
  cust_name: string;
  ord_amt: number;
  ord_stat: 'A' | 'C' | 'X';
}

// 新システムのドメインモデル (きれいなモデル)
interface Order {
  id: string;
  customerName: string;
  amount: number;
  status: 'active' | 'completed' | 'cancelled';
}

// ACL: レガシー → ドメインモデルに変換
function toOrder(legacy: LegacyOrder): Order {
  const statusMap = { A: 'active', C: 'completed', X: 'cancelled' } as const;
  return {
    id: legacy.ord_id,
    customerName: legacy.cust_name,
    amount: legacy.ord_amt,
    status: statusMap[legacy.ord_stat],
  };
}

ACL vs アダプター

ACL とアダプターの違いを以下にまとめる。

観点ACLアダプター
目的ドメインモデルの保護インターフェースの変換
スコープ境界づけられたコンテキストモジュール間
出自DDD で定義された概念GoF のデザインパターン

いつ使うか

変換層を立てるかどうかは、相手のデータモデルを自分たちのドメインに持ち込みたくないかどうかで決まる。

場面判断理由
レガシーシステムと統合する挟む相手の命名や不要なフィールドが新システムへ流れ込むのを防ぎ、customeruser のような用語の不一致を変換層の中で解消できる
旧システムを段階的に置き換える挟む移行が完了するまで両方のモデルが併存するため、対応表を変換層に集めておけば切り替え時に消す範囲がはっきりする
仕様を自分たちで決められない外部 API を使う挟む相手側の API 変更が変換層で吸収され、ドメインモデルと呼び出し側のコードを直さずに追随できる
同じシステム内のモジュール同士をつなぐ挟まない境界づけられたコンテキストをまたがず双方を直せるので、インターフェースを合わせるアダプターで足りる

現場での応用を知るには関連書籍も役立つ。

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

関連用語

関連する記事