DDD(Domain Driven Design) ドメイン駆動設計
DDD(Domain Driven Design)とは?
- ドメイン駆動設計。
- 精巧なオブジェクトシステムを作るのに役立つ原則とパターンの集合である。
- ビジネスDomainごとに分けて設計する方式である。
- 現実世界で出来事が発生する集合であるDomain(ドメイン)を中心に設計する方法である。
- 服のショッピングモールを例にすると、顧客が注文するドメイン、店主が管理するドメインなどがあり得る。
- このようなドメインが互いに相互作用しながら設計することがドメイン駆動設計である。
- ドメイン駆動設計ではドメインがそれぞれ分離されている。この観点からMSA(MicroService Architecture)を適用すると設計しやすい。
- DDDでは同じようなオブジェクトが存在し得る。例えば、服の購入者の立場では(name, price)のようなオブジェクト情報を持つが、販売者の立場では(madeDate, size, madeCountry)などがあり得る。つまり、文脈によってオブジェクトの役割が変わることがDDDである。
Ubiquitous Language(ユビキタス言語)
ドメインで使う用語をコードに反映しなければ、そのコードは開発者にコードの意味を解釈する負担を与える。コードの可読性を高めてコードを分析し理解する時間を節約し、用語が定義されるたびに用語集へ記録して明確に定義することで、後から、または他の人も共通の言語を使えるようにする。
ドメインとは?
- 一般的な要求事項、ソフトウェアで解決しようとする問題領域である。
- オンライン書店システムを実装するとすれば、オンライン書店がドメインになる。
- 1つのドメインはさらに複数のサブドメインに分けられる。
- オンライン書店のサブドメインは商品、会員、注文、精算、配送などになる。
- すべてのドメインに固定されたサブドメインが存在するわけではない。状況によって変わる。
- 対象が企業なのか、ユーザーなのかなど。
- 特定ドメインのためのソフトウェアだからといって、ドメインが提供すべきすべての機能を実装するわけではない。
- 外部業者の配送システムや決済システムなどを利用することもある。
ドメインモデル
- 特定のドメインを概念的に表現したものである。
- 現実世界を反映するが、現実世界のコピーではなく、実際の対象をよりよく理解できるように抽象化し具体化するものである。
- これを使うと、複数の関係者が同じ姿でドメインを理解し、ドメイン知識を共有するのに役立つ。
- ドメインを理解するには、ドメインが提供する機能と主要データ構成を把握する必要がある。
- 通常は機能とデータを一緒に見せるクラス図が適している。
- 必ずUMLだけを使わなければならないわけではない。ドメイン理解に役立つなら表現方法は重要ではない。
- 複数のサブドメインを1つの図にモデル化してはいけない。
- 各サブドメインごとに別々のモデルを作る必要がある。
- モデルの各構成要素は、特定のドメインに限定されて初めて意味が完全になるためである。
- カタログの商品と配送の商品は異なる。
Entity、VO
- Entity
- テーブルモデルであり、一意な識別子を持つ。
- 一意な識別子(primary key)を基にオブジェクトの同一性を与える。
- VO(Value Object)
- データ表現モデルで、識別子を持たず不変型である。
- 状態(Attribute)を基にオブジェクトの同一性を与える。
Javaで簡単に説明すると、equalsとhashCodeをidだけで判断するならEntityであり、状態に関するすべての情報で判断するならVOである。
ドメインアグリゲート(Aggregate)
- 互いに関連するドメインモデルの集合、関連オブジェクトのまとまりをアグリゲートと言う。
アグリゲートルート
- アグリゲートに属するオブジェクトが一貫した状態を保つには、アグリゲート全体を管理する主体が必要である。
- ルートエンティティはアグリゲートの代表エンティティであり、アグリゲートに属するエンティティはルートエンティティに直接または間接的に属する。
- アグリゲートルートの核心的な役割は、アグリゲートの一貫性が崩れないように調整することである。
- アグリゲートルートは、アグリゲートが提供すべきドメイン機能を提供する。
- 注文アグリゲートのルートエンティティOrderは、関連機能を実装したメソッドを提供する。
- 配送先変更、商品変更など。
- 注文アグリゲートのルートエンティティOrderは、関連機能を実装したメソッドを提供する。
ドメインモデルパターン
- 一般的なアプリケーションのアーキテクチャは4つの領域(階層)で構成される。
Presentation: 表現(UI)領域
- ユーザーのリクエストを受け取り、アプリケーション領域へ伝える。
- Spring MVCフレームワークが表現領域のための技術に該当する。
- Webアプリケーションで表現領域のユーザーは、Webブラウザを使う人である場合もあり、REST APIを呼び出す外部システムである場合もある。
Application: アプリケーション領域
- 処理結果を再びユーザーに見せる役割を持つ。
- 業務ロジックを直接実装せず、ドメイン階層を組み合わせて機能を実行する。
- 主にドメインとRepositoryを基に、実際のサービス(API)を提供する階層である。
Domain: ドメイン領域
- システムが提供するドメインの規則を実装する。
- Entity、VO(Value Object)を活用してドメインロジックが進む階層である。
Infrastructure: インフラストラクチャ領域
- 永続性を実装したり、外部システムとの連携を処理したりする。
- つまり、外部との通信、DB、NoSQL、Messagingなどを担当する階層である。