ソフトウェア開発には、常に存在する課題があります。それは、ビジネスロジックが複雑化するにつれて、コードの保守がますます困難になるということです。MVCアーキテクチャに基づいた初期のCRUDアプリケーションはうまく機能しますが、ビジネスニーズが深まるにつれて、開発チームはすぐに「ビジネスロジックはどこに配置すべきか?」というジレンマに陥ります。
この問題を解決するために、ドメイン駆動設計(DDD)が開発されました。2003年にソフトウェアの第一人者であるエリック・エバンスによって提唱されたDDDは、ビジネスドメインの知識をシステム設計の中核的な推進力として活用することで、ビジネスニーズに高度に合致したソフトウェアモデルを構築することを目的としています。DDDは特定のアーキテクチャスタイルではなく、境界を明確にすることで複雑なビジネスドメインを簡素化し、ドメインとアプリケーションの境界を明確に設計するのに役立つ、包括的かつ体系的な設計手法です。
この記事では、DDDの中核となる概念、戦略的・戦術的な設計、そして階層型アーキテクチャについて体系的に解説します。DDDを初めて学ぶ開発者の方、あるいはアーキテクチャ設計能力の向上を目指すプロダクトマネージャーやアーキテクトの方など、どなたにも役立つ内容となっています。
従来の開発モデルでは、ビジネスロジックがデータベース操作やフレームワーク機能と密接に絡み合っていることが多く、コードの可読性の低下や保守コストの増大につながっていました。DDD(ドメイン駆動設計)の核心的な考え方は、純粋なビジネスロジックを技術的な実装から完全に分離し、開発者がビジネスエキスパートのように考えることができるようにすることです。
DDDの第一の原則は、共通言語を確立することです。開発者、テスター、プロダクトマネージャー、ビジネスエキスパートなど、すべての関係者が、統一されたドメインモデルベースの共通言語を使用する必要があります。つまり、コード内のクラス名やメソッド名は、DataProcessorやManagerといった曖昧な用語ではなく、ビジネスコンセプトを直接反映したものでなければなりません。例えば、eコマースシステムであれば、すべてのロジックを詰め込んだ汎用的なOrderServiceではなく、Orderクラスとそのplace()メソッドを持つべきです。
DDDの2つ目の重要な概念は、コアドメインに焦点を当てることです。複雑なビジネスシステムでは、異なるサブドメインはそれぞれ異なるビジネス価値を持っています。コアドメインはビジネスの成功を左右する重要な要素であり、最も多くの設計労力を必要とします。共通ドメインは複数のサブドメインで共有される共通の機能であり、サポートドメインは他のサブドメインを支えるインフラストラクチャです。
DDD(ドメイン駆動設計)の実践には、戦略的設計と戦術的設計という2つの側面があります。戦略的設計は、ドメインの分割と境界の定義に焦点を当て、「何をすべきか」という問題を解決します。一方、戦術的設計は、具体的なコードの実装に焦点を当て、「どのようにすべきか」という問題を解決します。

大規模なシステムを扱う場合、単一のモデルで全ての業務領域を網羅しようとするのは非現実的です。DDDの戦略的設計部分は、複雑なシステムを分割するための強力なツールを提供します。
ドメインとは、企業が解決すべき問題領域を指します。コンテンツコミュニティシステムを例にとると、「コンテンツコミュニティ」全体がドメインであり、ユーザー管理、読者、決済、コミュニティといった複数のサブドメインに分割できます。その中で、コミュニティはコアドメインに属し、決済はサポートドメインに属すると考えられます。
重要なポイント:戦略立案においては、事業の中核となる能力がどのサブドメインにあるかを特定し、そこにリソースを集中させることが重要です。

これは、DDD(データ需要と意思決定)において最も重要な戦略的パターンです。モデルの適用範囲を明確に定義し、「この単語はどの境界内で意味するのか?」を明確にします。例えば、eコマースの商品においては、「製品」には価格、説明、カテゴリなどの属性が含まれますが、物流においては、「製品」は重量や容積に重点が置かれます。
各境界コンテキストは独立した「意味境界」であり、統一された共通言語とドメインモデルを持つ。したがって、システムは複数の高度に凝集した、疎結合なモジュールに分解される。
基本原則:境界コンテキストは、コンテキストマッピングを通じて他のコンテキストとの関係を明確にし、モデルの汚染を回避する。

DDD(データ依存性分析)とマイクロサービスアーキテクチャは、まさに相性の良い組み合わせです。適切に設計された境界コンテキストは、マイクロサービスの候補として最適です。逆に、システムを技術レイヤーごとに盲目的に分割すると、分散型モノリスになりがちです。サービスは分離されていても、結合度は残ってしまうからです。マイクロサービスアーキテクチャでは、サービスは集約よりも小さくなく、境界コンテキストよりも大きくあってはなりません。
限定されたコンテキスト内では、DDDはドメインモデルを構築するための戦術的なモデリングツール群を提供する。
エンティティとは、一意の識別子とライフサイクルを持つオブジェクトのことです。例えば、ユーザーが名前を変更しても、一意のIDは変わらず、同じエンティティとして扱われます。エンティティは通常、リッチネスモデルを採用しており、ビジネス上の動作はエンティティ内にカプセル化されています。
値オブジェクトは一意の識別子を持たず、属性値のみによって区別され、通常は不変です。たとえば、金額(Money)は通貨と値によって決まります。同じ金額と通貨を持つ2つのMoney値は互換性があります。値オブジェクトを適切に使用することで、システムの複雑さを軽減できます。たとえば、住所、メールアドレス、電話番号はすべて値オブジェクトとしてモデル化できます。
集約とは、関連するエンティティと値オブジェクトの集合であり、全体として管理されます。集約ルートは集約の中核となるエンティティであり、集約内の一貫性を維持する役割を担います。例えば、Order集約ルートはOrderItemエンティティとPaymentエンティティを管理します。注文アイテムへのアクセスはすべてOrderを介して行う必要があります。
集約設計の原則:集約境界内のトランザクションは一貫性を維持するべきである。他の集約への参照は識別子を介してのみ行い、集約間での直接参照は避けるべきである。集約は可能な限り小さく設計されるべきである。
これは初心者がしばしば混乱する概念です。ドメインサービスは、エンティティや値オブジェクトに帰属できないドメイン動作を担います。ドメイン層に属し、ドメインの純粋性を維持し、技術的な詳細には関与しません。例えば、TransferServiceは口座間送金を処理しますが、特定の口座エンティティには属さず、コアとなるビジネスロジックです。
アプリケーションサービスは、ドメインオブジェクトとドメインサービスを調整し、アプリケーションのワークフローを処理し、アプリケーション層に属します。アプリケーションサービスはステートレスであり、ユースケースのスケジューリング、トランザクション管理、セキュリティ認証を担当しますが、ビジネスルールは含みません。
リポジトリは、ドメイン層とインフラストラクチャ層の間の橋渡し役を果たします。ドメイン層では抽象インターフェースとして定義され、インフラストラクチャ層は具体的なストレージロジックを実装します。リポジトリは集約によるアクセス方法のみを公開し、ORMの詳細情報は公開しません。
ドメインイベントとは、ドメイン内で発生する意味のあるビジネスイベントであり、後続のビジネスロジックをトリガーしたり、モジュール間の結合度を分離したりするために使用できます。

DDD(ドメイン駆動設計)では、通常、ユーザーインターフェース層、アプリケーション層、ドメイン層、インフラストラクチャ層の4つの層からなる階層型アーキテクチャを推奨しています。
このコンポーネントは、ユーザーとのやり取り、リクエストの受信、レスポンスの返送を担当します。Webアプリケーションにおいてはコントローラーに相当しますが、パラメーターの検証と結果のフォーマットのみを担当し、ビジネスロジックは含みません。
ドメインオブジェクトは、トランザクション境界、セキュリティ、認証を処理し、ビジネスユースケースを完了するために調整されます。アプリケーション層サービスはステートレスであり、ドメインサービスまたは集約ルートメソッドを呼び出すだけで、ビジネスルールは含まれません。
DDDの中核は、すべてのビジネスルールとモデルを含みます。集約ルート、エンティティ、値オブジェクト、ドメインサービスを定義することで、ビジネスロジックの整合性を確保します。
データベースアクセス、メッセージキュー、外部API呼び出しなどの技術的な実装サポートを提供します。依存関係逆転の原則に基づき、ドメイン層がインターフェースを定義し、インフラストラクチャ層がそれを実装することで、ビジネスロジックと技術実装の完全な分離を実現します。
DDD(ドメイン駆動設計)の階層型アーキテクチャでは、依存関係は外側から内側へと導かれます。つまり、ユーザーインターフェース層はアプリケーション層に依存し、アプリケーション層はドメイン層に依存し、インフラストラクチャ層のインターフェースは、依存関係の逆転によってドメイン層によって定義されます。ドメイン層は特定のフレームワークやテクノロジーに依存しないため、コアとなるビジネスロジックを修正することなく、代替テクノロジーに置き換えることができます。

DDD(ドメイン駆動設計)の実践において、可視化はチームの合意形成を支援する上で重要なステップです。戦略設計フェーズにおける境界コンテキストの明確化であれ、戦術設計フェーズにおけるドメインモデルの構築であれ、明確な図は不可欠です。ProcessOnは、プロフェッショナルなオンライン図作成ツールとして、DDDアーキテクチャのプロセス全体の可視化を効率的にサポートします。
1. ProcessOnのプロフィールページにアクセスして「フローチャート」を作成するか、テンプレートコミュニティで「DDDアーキテクチャ設計」などのキーワードを検索してください。
2. 左側の「その他のグラフィック」では、フローチャートやUML図などのグラフィックカテゴリを選択して、グラフィックライブラリに追加できます。グラフィックライブラリから長方形や円などの図形をキャンバスにドラッグ&ドロップし、矢印付きの線を使って異なる要素を接続し、依存関係を表現できます。
3. 1つまたは複数の要素が選択されると、上部のツールバーは異なる色を使用してモデルの異なるレベルを区別したり、グラフィックの配置やレイヤー設定などのレイアウト調整を実行したりできます。

4. 図が完成したら、右上隅にある共有コラボレーションボタンをクリックして、DDDアーキテクチャ図を同僚や顧客と共有し、モデルの継続的な反復作業を行うことができます。また、高解像度画像、PDF、SVGなどの形式でエクスポートして、後で参照することも可能です。
ドメイン駆動設計は、単なる技術パターンやアーキテクチャ仕様の集合体ではありません。それは思考の革命であり、ソフトウェアの中核的な複雑さに対処するための体系的な方法論です。ソフトウェア開発はテーブルを作成することから始まるのではなく、ビジネスを理解することから始まるということを教えてくれます。
DDDは、ドメイン境界を戦略的に定義し、高度に凝集性の高いドメインモデルを戦術的に設計するとともに、ビジネスロジックを技術的な実装から分離する階層型アーキテクチャを組み合わせることで、複雑なビジネスシステムの保守性と拡張性を大幅に向上させることができます。特にマイクロサービス時代においては、DDDが提供する境界コンテキスト分割手法は、マイクロサービスを科学的に分解するための最良の手法です。