DDD(ドメイン駆動設計)とは?メリットから導入手順までわかりやすく解説
この記事は以下のような方にオススメです
- Web/業務系システムのテックリード
- 中規模開発チームのリードエンジニア
- プロダクトマネージャー/プロダクトオーナー
複雑なソフトウェア開発において、ビジネスサイドと開発サイドの間に認識のギャップが生じることは珍しくありません。
DDD(ドメイン駆動設計)は、このギャップを埋め、ビジネスの本質に焦点を当てた設計手法として注目を集めています。
本記事では、DDDの基本概念から実践的な導入ステップまで、体系的に解説します。複雑なビジネスロジックを扱うプロジェクトでも、持続可能なシステム開発が可能になるでしょう。
目次
DDD(ドメイン駆動設計)とは?
DDDとは、2003年にエリック・エヴァンスが著書「Domain-Driven Design」で提唱したソフトウェア開発手法です。この設計アプローチの核心は、ビジネスの専門領域(ドメイン)を中心に据え、ソフトウェア設計をビジネスの実態に合わせることにあります。
従来の技術中心の設計と異なり、DDDではビジネスの専門家とソフトウェア開発者が共通言語(ユビキタス言語)を用いて密にコミュニケーションを取りながら、ドメインモデルを構築します。
これにより、ビジネスの変化に強く、長期的に保守可能なシステムの構築が可能になるのです。
DDD(ドメイン駆動設計)のメリット
![]()
ここからはDDDのメリットについて詳しく見ていきましょう。
要件定義が正確になりやすい
DDDでは、ビジネスドメインの専門家と開発者が共通言語(ユビキタス言語)を使って対話するため、要件定義の精度が向上しやすくなります。従来の開発では技術用語とビジネス用語の乖離から誤解が生じやすい問題がありましたが、DDDではドメイン知識を明確に言語化し、モデルとして表現します。これにより抽象的な要件が具体化され、関係者間の認識の齟齬が大幅に減少します。
コミュニケーションが取りやすい
DDDの最大の強みの一つは、ビジネス側と開発側の間でコミュニケーションが格段に取りやすくなる点です。ユビキタス言語を共有することで、専門用語の誤解や解釈の違いによる行き違いが大幅に減少します。
例えば、仕様変更の際も共通の言語で議論できるため、「それはできない」「仕様が曖昧」といった不毛なやり取りが減り、建設的な対話が可能になります。また、レビュー時にもビジネス担当者がコードの意図を理解しやすくなり、本当に必要な機能が実装されているかの確認がスムーズに行えます。
ビジネスロジックの明確化
DDDの最大の強みの一つは、ビジネスの変化に強い設計を実現できる点です。ドメインモデルをインフラやアプリケーション層から適切に分離・独立させて設計すれば、仕様変更や機能追加が発生しても、影響範囲を特定のコンテキスト内に局所化できます。
例えば、あるビジネスルールが変更になった場合、関連する集約やエンティティを中心に修正すればよく、システム全体への変更の波及を最小化できます。
DDDを導入すべきケースと避けるべきケース

DDDの導入は全てのプロジェクトに適しているわけではありません。ここからはDDDを導入すべきケースと避けるべきケースの基準はどこにあるのかを見ていきましょう。
導入すべきケース
まずは導入すべきケースについて解説します。
ビジネスルールが複雑
ビジネスルールが複雑な領域は、DDDの真価が発揮されます。金融商品の取引ルール、保険の査定基準、物流の配送ルールなど、多くの条件分岐や例外処理が存在する場合、従来の設計手法では表現しきれないことが多いです。
特に会計システムでは税制改正への対応、物流システムでは配送条件の複雑な組み合わせ、医療システムでは診療報酬制度の変更など、ビジネスルールが複雑で変化しやすい領域では、ドメインモデルを中心に据えることで変更の影響範囲を限定できます。
変更要求が頻繁に発生する
顧客ニーズの急速な変化や法制度の改正が頻繁に発生する業界では、DDDの採用が大きな効果を発揮します。DDDはドメインモデルを中心に設計するため、ビジネスルールの変更をモデルに直接反映させやすいからです。
例えば、金融サービスや医療システムなど、規制変更が頻繁に起こる分野では、「法改正に伴うビジネスルールの変更」などに素早く対応できるのがDDDの強みです。ドメインエキスパートとの継続的な対話を通じてモデルを進化させる文化が根付いていれば、変更を恐れずにシステムを成長させていくことができます。
長期的な運用を想定している
システムの寿命が数年以上にわたる長期プロジェクトでは、DDDの導入が特に効果的です。DDDを採用することで、ドメインの本質的な部分と技術的実装を分離できるため、将来の変更に柔軟に対応できる基盤が整います。
特に重要なのは、長期運用中に蓄積されるドメイン知識の活用です。DDDではドメインモデルが明確に表現されるため、年月を経てチームメンバーが入れ替わっても、システムの本質的な意図が失われにくくなります。
複数チームで開発している
複数チームが同時並行で開発を進めるプロジェクトでは、DDDの導入が大きな効果を発揮します。チームごとに担当する境界づけられたコンテキストを明確に分離することで、各チームが独立して作業できるようになるからです。
例えば、「注文管理チーム」「在庫管理チーム」「顧客管理チーム」といった分け方をすると、各チームはそれぞれのドメイン知識に特化した開発に集中できます。
避けるべきケース
次にDDDを避けるべきケースについて見ていきましょう。
ドメインが単純
ドメインが単純なシステムでは、DDDの導入は過剰な設計になりがちです。例えば、単純なCRUD操作が中心のシステムや、ビジネスルールがほとんど存在しない管理画面などが該当します。
このようなケースでは、エンティティや値オブジェクトを厳密に分けたり、集約を設計したりする労力が、得られる恩恵を上回ってしまいます。
小規模なマスタメンテナンスや単純な情報閲覧システムなどは、一般にDDDを適用するよりも軽量なアプローチを選ぶ方が、開発効率と保守性の観点から合理的です。
短期間・小規模の開発
短期間・小規模の開発プロジェクトでは、DDDの導入は適していません。数週間で完成させる必要があるWebサイトや、1〜2人の開発者で構築する小規模アプリケーションでは、DDDの学習コストや設計オーバーヘッドが大きすぎます。
納期が厳しい案件では、ドメインモデルの精緻化やユビキタス言語の構築に時間を割くよりも、シンプルなCRUD操作を中心とした実装に集中した方が効率的です。小規模チームでは複雑なコミュニケーション問題が少なく、DDDの恩恵を受けにくい傾向があります。
一度きりのリリースで終了
一度きりのリリースで終わるプロジェクトでは、一般にDDDはコストパフォーマンスが悪くなりがちです。DDDの真価は継続的な開発と運用の中で発揮されるものだからです。
例えば、イベント用の一時的なWebサイトや、特定のキャンペーン向けの短期間だけ使用するアプリケーションなどは、ドメインモデルの精緻な設計や境界づけられたコンテキストの分析に時間を費やすよりも、シンプルなアーキテクチャで素早く開発することが合理的です。
技術主導のユーティリティ開発
技術主導のユーティリティ開発では、ビジネスロジックよりも技術的な実装が中心となることが多く、一般にDDDの効果は限定的です。例えば、外部APIとの連携システムや、データ変換ツール、バッチ処理フレームワークなどがこれに該当します。
また、ユーティリティ系の開発では、ビジネスルールよりも技術的な制約条件が設計を左右することが多いため、技術的な関心事に基づいた設計アプローチの方が適切です。
戦略的DDDと戦術的DDD

ドメイン駆動設計(DDD)は「戦略的DDD」と「戦術的DDD」という二つの側面から構成されています。戦略的DDDはビジネスドメインの全体像を捉え、境界づけられたコンテキストやコンテキストマップを用いて、複雑なドメインを管理可能な単位に分割する手法です。
一方、戦術的DDDはより具体的なコードレベルの設計に焦点を当て、エンティティ、値オブジェクト、集約、リポジトリ、ドメインイベントなどの概念を用いてドメインモデルを実装します。
戦略的DDDの基本概念
ここからは戦略的DDDの基本的な概念について詳しく解説します。
ドメイン
ドメインとは、ソフトウェア開発の対象となるビジネス上の問題領域のことを指します。例えば、銀行システムであれば「口座管理」「融資」「投資」などは、銀行ドメインのサブドメインとして扱われます。
DDDにおいて、ドメインを深く理解することは最も重要な出発点です。開発者はドメインエキスパートと密接に協力し、業務の本質的な知識を獲得する必要があります。この理解なしには、いくら技術的に優れたシステムを構築しても、ビジネス価値を最大化することはできません。
ドメインモデル
ドメインモデルとは、ビジネスドメインの概念やルール、振る舞いを抽象化して表現した設計モデルです。
ドメインモデルの中核には、エンティティ、値オブジェクト、集約といった要素が含まれており、これらを通じてビジネスの実態を正確に反映します。例えば、ECサイトであれば「注文」「顧客」「商品」などの概念とそれらの関係性や制約条件が表現されます。
ユビキタス言語
ユビキタス言語とは、開発チームとドメイン専門家が共通して使用する言語のことです。各境界づけられたコンテキスト内で、コード・設計文書・会話にわたって一貫した用語を使うことで、コミュニケーションの齟齬を防ぎます。
技術者は技術用語を、ビジネス側は業務用語を使いがちですが、これが誤解や認識のズレを生む原因となります。ユビキタス言語を確立することで、全員が同じ言葉で同じ概念を指すようになり、要件の解釈ミスや実装の誤りを減らせます。
境界づけられたコンテキスト
境界づけられたコンテキストは、ドメインモデルの適用範囲を明確に区切る重要な概念です。同じ用語でも、部門やチームによって異なる意味を持つことがあるため、その混乱を防ぐために境界を設けます。
例えば「顧客」という言葉は、営業部門では「契約を結んだ企業」を指し、サポート部門では「問い合わせをしてくる個人」を指すことがあります。このように異なるモデルが衝突しないよう、明確な境界を定義することで、各コンテキスト内では一貫した用語の使用と解釈が可能になります。
コンテキストを分けた後に必要になる設計
境界づけられたコンテキストを識別して終わりではなく、それらが連携して動作する必要があります。この段階では、各コンテキスト間のデータの流れや相互作用のルールを明確に定義しなければなりません。
例えば、あるコンテキストで発生したイベントが他のコンテキストにどのように伝播するのか、共有すべき情報は何か、そしてそれぞれのコンテキストがどのような責任を持つのかを決定します。
コンテキストマップの役割

コンテキストマップは、境界づけられたコンテキスト間の関係性を視覚化し、明確に定義する重要な設計成果物です。
具体的には以下の要素を明示します。
- 各コンテキストの境界と責任範囲
- コンテキスト間の依存関係の方向性
- 採用している統合パターン
- 翻訳層の存在
このマップは静的なドキュメントではなく、プロジェクトの進行とともに進化し続ける生きた設計資産といえるでしょう。
コンテキスト間の代表的な統合パターン
境界づけられたコンテキスト間の統合は、DDDにおいて重要な設計判断の一つです。場当たり的な連携方法を選ぶと、時間の経過とともにシステム全体の設計が劣化し、保守性が低下していきます。
ここからはコンテキスト間の代表的な統合パターンについて見ていきましょう。
境界づけられたコンテキスト間の連携では、関係・協調パターンとして「Shared Kernel」「Customer-Supplier」「Conformist」がよく用いられます。
【Shared Kernel】
複数のチームが一部のコードやモデルを共同で管理・共有するパターンです。このパターンは両チームが対等な関係にあり、密に協力できる場合に有効です。ただし、変更の調整コストが高く、一方のチームが勝手に変更すると他方に影響するリスクがあります。
【Customer-Supplier】
上流チーム(Supplier)と下流チーム(Customer)の関係が明確な場合に使用します。上流チームは下流チームのニーズを考慮しながら開発を進め、下流チームは上流の提供するAPIやインターフェースに合わせて実装します。このパターンでは下流チームの要求が上流に反映される交渉力が重要です。
【Conformist】
下流チームが上流チームのモデルをそのまま採用するアプローチです。上流チームとの交渉力がない場合や、外部システムとの連携で使用されます。このパターンではモデルの不一致による複雑さは減りますが、自チームのドメインに最適ではないモデルを使用する妥協が必要です。
これらのパターンは組織構造やチーム間の力関係、プロジェクトの性質に応じて選択することが重要です。
Anti-Corruption Layer(腐敗防止層)
Anti-Corruption Layerは、外部システムや他のコンテキストからの概念や設計が自分たちのドメインモデルを「汚染」することを防ぐ設計パターンです。
例えば、レガシーシステムと新システムを連携させる場合、レガシーシステムの古い概念や構造がそのまま新システムに流れ込むと、新しく設計したドメインモデルの整合性が損なわれてしまいます。Anti-Corruption Layerは、このような「腐敗」を防ぐ防波堤として機能します。
この層が特に必要となるのは以下のようなケースです。
- 自分たちがコントロールできない外部システムと統合する場合
- レガシーシステムを段階的に置き換える移行期間中
- 他チームが管理するコンテキストとの連携で、モデルの考え方に大きな違いがある場合
統合パターンの選び方

統合パターンを選ぶ際は、まずコンテキスト間の変更頻度を考慮しましょう。頻繁に変更が発生する関係では、Anti-Corruption Layerのような疎結合なパターンが適しています。
次に、各チームの責任範囲と権限を明確にします。上流チームが下流チームに配慮できる関係ならCustomer-Supplierが、そうでなければConformistが現実的な選択となります。
さらに、チーム構造も重要な判断材料です。同一チームが複数のコンテキストを担当する場合はShared Kernelが効率的ですが、組織が大きくなるにつれて境界を明確にしたパターンが有効になります。
戦術的DDDの基本概念
戦術的DDDでは、ビジネスルールやドメインの知識をコードとして表現するために、明確な構造が定義されています。エンティティ、値オブジェクト、集約、リポジトリ、サービスなどの概念を活用することで、ドメインの複雑さを適切に管理できるようになります。
ここからは戦術的DDDの各要素について解説します。
エンティティ
エンティティとは、各境界づけられたコンテキスト内で一意の識別子によって区別されるオブジェクトです。顧客、注文、商品などがエンティティの代表例で、ライフサイクルを通じて同一性が保たれます。エンティティの最大の特徴は、属性が変化しても同じものとして認識される点にあります。
たとえば、顧客がメールアドレスや住所を変更しても、その顧客は同じ人物として扱われます。このような同一性の概念がエンティティの核心です。
値オブジェクト
値オブジェクトとは、その属性値によってのみ同一性が定義される不変なオブジェクトです。エンティティが「何であるか(ID)」で識別されるのに対し、値オブジェクトは「どのような値を持つか」で等価性が判断されます。例えば、お金や日付、住所などが典型的な値オブジェクトです。
集約と集約ルート
集約とは、関連するオブジェクト群を一つの整合性単位としてまとめたものです。複雑なドメインモデルを管理しやすい単位に分割する重要な概念です。各集約には必ず一つの集約ルートが存在し、これが集約全体の一貫性と整合性を保証します。
例えば、注文システムでは「注文」が集約ルートとなり、「注文明細」や「配送先情報」などは集約内部のエンティティや値オブジェクトとして扱われます。
リポジトリ
リポジトリは集約ルートの永続化と取得を担当する抽象化レイヤーです。データベースやファイルシステムなどのインフラストラクチャの詳細をドメインモデルから隠蔽し、純粋なドメインロジックに集中できる環境を提供します。リポジトリを使うことで、「商品を検索する」「注文を保存する」といったドメイン用語でデータアクセスを表現できるようになり、技術的な実装の詳細からドメインモデルを守ることができます。また、リポジトリはインターフェースとして定義され、実装はインフラ層で行われるため、データストアの変更にも柔軟に対応できる設計となっています。
サービス
サービスは、特定のオブジェクトに自然に属さない操作や、複数のオブジェクトを横断する処理を表現するために使用され、「ドメインサービス」「アプリケーションサービス」「インフラストラクチャサービス」といった区分で扱われます。例えば、料金計算や在庫引当のような、単一のエンティティに閉じ込められないビジネスロジックはドメインサービスとして実装されます。
一方、アプリケーションサービスはドメインロジック自体は持たず、ユースケース実行の調整やトランザクション管理を担当します。外部決済ゲートウェイの呼び出しや認証/認可処理はアプリケーション層またはインフラ層のサービスに置くのが一般的です。
適切なサービス設計により、ドメインモデルの凝集度を高めながら、必要な機能を柔軟に実装できます。
アプリケーション層
アプリケーション層はドメイン層とユーザーインターフェース(UI)層の間に位置し、ユーザーの意図をドメインオブジェクトの操作に変換し、ビジネスフローを実現します。
例えば、注文処理のユースケースでは、
- • 顧客エンティティの取得
- • 商品の在庫確認
- • 注文エンティティの作成
- • リポジトリへの保存
といった一連の処理を調整するのがアプリケーション層です。
DDD実装のためのステップ

ドメイン駆動設計(DDD)を実装するには、体系的なアプローチが必要です。成功するDDD導入のためには、単なる技術的な実装だけでなく、ビジネスドメインの深い理解から始める必要があります。
以降のセクションでは、具体的な実装ステップについて解説します。
①現状ドメインの可視化
DDDを実践するには、現状のドメインを可視化することから始めます。この段階では、イベントストーミングやドメインストーリーテリング、ユーザーストーリーマッピングなどの手法を活用し、業務の流れや関係性を図式化します。
特に効果的なのは、現場の担当者を交えたワークショップ形式での作業です。実際の業務に携わる人々の声を直接聞くことで、マニュアルには書かれていない暗黙知や例外的な処理を発見できます。
②ユビキタス言語の整備
ドメインの可視化が出来たら、次はユビキタス言語の整備です。
ドメインエキスパートとの対話を通じて業務で使われている専門用語や概念を丁寧に抽出します。これらの用語の定義を明確にし、チーム全員が同じ理解を持てるように用語集を作成しましょう。
この用語集は単なる文書ではなく、「生きた辞書」として常に更新され続けるべきものです。開発者、ビジネス担当者、テスターなど、全ての関係者がこの言語を日常的に使うことで、認識のズレを防ぎます。
③境界づけられたコンテキストの切り出し
ドメインとユビキタス言語を整理したら、次は実際にシステムを分割するコンテキストの境界を明確にしていきます。この工程では、ビジネスの関心事や責任範囲に基づいて、システム全体を適切なサイズの「境界づけられたコンテキスト」に分割します。
各コンテキストの切り出しでは、チーム構成や組織構造を考慮することが重要です。コンウェイの法則にもあるように、システム設計は組織構造を反映する傾向があるため、責任範囲が明確になるよう境界を設定しましょう。
④ドメインモデルの設計と実装
ドメインモデルの設計と実装は、DDDプロセスの核心部分です。この段階では、前工程で特定したコンテキスト内で、実際に動作するモデルを作り上げていきます。
まず、エンティティと値オブジェクトを識別することから始めましょう。
次に、関連するエンティティと値オブジェクトをまとめて集約を形成します。他の集約など外部からの参照・変更は集約ルート経由に限定することで、集約内の不変条件を保ちやすくなります。エンティティや値オブジェクトに自然に属さず、しばしばステートレスなドメイン上の操作はドメインサービスとして表現します。
⑤リポジトリ・アプリケーション層の実装
ドメインモデルを設計したら、次はそれらを永続化するためのリポジトリと、ユースケースを実行するアプリケーション層を実装します。リポジトリはドメインオブジェクトの保存と取得を担当し、インフラストラクチャの詳細からドメインを保護します。
アプリケーション層はユースケースのオーケストレーターとして機能します。
この層の実装では、サービスクラスやユースケースクラスを作成し、各ビジネスユースケースを明示的なAPIとして公開します。
⑥継続的リファクタリングとドメイン知識の更新
DDDの実装は一度で完成するものではなく、継続的な改善プロセスが不可欠です。ビジネスドメインの理解が深まるにつれて、初期モデルの不完全さや誤りが明らかになってきます。このため、定期的なリファクタリングを通じてドメインモデルを洗練させていくことが重要です。
実際の運用から得られた知見をモデルに反映させることで、より現実に即した設計へと進化させることができます。また、ドメインエキスパートとの定期的な対話を続け、ユビキタス言語を更新し続けることも重要です。ビジネスの変化に伴い、言語も進化するからです。
まとめ
ドメイン駆動設計(DDD)は、複雑なビジネスロジックを持つシステム開発において非常に効果的なアプローチです。ドメインの知識を中心に据え、ユビキタス言語を通じてビジネスと開発のギャップを埋めることで、より価値の高いソフトウェアを実現できます。
DDDの導入は段階的に進めることで、変更に強く、ビジネス価値を最大化するシステム開発が可能になります。最も重要なのは、技術だけでなくビジネスドメインへの深い理解と、それを反映させるための継続的な対話です。適切な場面でDDDを活用することで、複雑なビジネス要件に対応する持続可能なシステムを構築できるでしょう。
各種お問い合わせ