ドメイン駆動設計 (DDD)

ビジネスドメインの知識を中心に据え、ドメインエキスパートと開発者が共通言語で協働しながらソフトウェアを設計する手法

DDD設計

ドメイン駆動設計とは

ドメイン駆動設計 (Domain-Driven Design, DDD) は、Eric Evans が 2003 年の著書で体系化したソフトウェア設計手法である。ビジネスドメイン (業務領域) の知識をソフトウェアの中心に据え、ドメインエキスパート (業務の専門家) と開発者がユビキタス言語 (共通言語) を使って協働しながら、ドメインモデルを構築する。

DDD の核心は「ソフトウェアの複雑さの本質はビジネスドメインにある」という認識だ。技術的な複雑さ (フレームワーク、データベース、インフラ) は手段にすぎず、ビジネスの複雑さを正確にモデル化することが最も重要な設計活動である。

戦略的設計と戦術的設計

DDD は 2 つのレベルで構成される。

戦略的設計 (Strategic Design) は、大きな視点でシステムの境界と関係を定義する。

  • ユビキタス言語: チーム内で統一された用語体系。コード、会話、ドキュメントすべてで同じ言葉を使う
  • 境界づけられたコンテキスト: ドメインモデルが一貫した意味を持つ範囲
  • コンテキストマップ: コンテキスト間の関係と統合パターン

戦術的設計 (Tactical Design) は、コンテキスト内部のモデルを具体的に実装する。

  • エンティティ: 一意の識別子を持つオブジェクト (例: 注文、ユーザー)
  • 値オブジェクト: 識別子を持たず、属性の組み合わせで等価性を判断するオブジェクト (例: 金額、住所)
  • 集約: トランザクション整合性の単位
  • ドメインイベント: ドメインで発生した重要な出来事
  • リポジトリ: 集約の永続化と取得を担うインターフェース

ユビキタス言語の重要性

DDD で最も重要かつ最も軽視されがちなのがユビキタス言語だ。開発者が「ユーザーテーブルのレコード」と呼び、業務担当者が「会員」と呼ぶ場合、コミュニケーションのたびに翻訳コストが発生する。コード上の変数名が userRecord で、業務用語が「会員」なら、コードを読んでもビジネスの意図が伝わらない。

ユビキタス言語では「会員」に統一し、コード上も member と命名する。これにより、コードがドメインの知識を直接表現するようになる。

実務での適用判断

DDD が有効なのは、ビジネスロジックが複雑なドメインだ。金融、物流、医療、保険など、業務ルールが多岐にわたり、ドメインエキスパートの知識なしには正しいソフトウェアを作れない領域で威力を発揮する。

逆に、CRUD 中心のシンプルなアプリケーション (ブログ、TODO アプリなど) に DDD を適用すると、過剰な抽象化でコードが複雑になるだけだ。DDD の戦術的パターン (エンティティ、値オブジェクト、リポジトリ) だけを形式的に導入しても、ユビキタス言語とドメインモデリングの本質を伴わなければ効果は薄い。

Eric Evans の「ドメイン駆動設計」が原典であり、「実践ドメイン駆動設計」(Vaughn Vernon 著) が実装面を補完する。日本語では「ドメイン駆動設計入門」(成瀬允宣 著) が入門書として広く読まれている。

DDD の主要概念

概念 説明
エンティティ ID で識別 ユーザー、注文
値オブジェクト 値で比較 金額、住所
集約 整合性の境界 注文 + 注文明細
リポジトリ データアクセスの抽象化 OrderRepository
class Order {
  constructor(private items: OrderItem[]) {}
  addItem(item: OrderItem) { this.items.push(item); }
  get total() { return this.items.reduce((s, i) => s + i.price, 0); }
}

ドメイン駆動設計 (DDD) の関連書籍も参考になる。

関連用語