ドメイン駆動設計(DDD)とは、業務領域の理解を中心に置き、業務の言葉とモデルをコードへ反映する設計アプローチです。
一言でいうと
DDDは、技術からではなく「その業務で何が大事か」から設計を始める考え方です。
DBテーブルや画面から先に考えるのではなく、注文、請求、在庫、契約、承認など、業務上の概念を整理します。
なぜ必要か
業務が複雑になると、単純なCRUDだけでは表現しきれないルールが増えます。
- 状態によってできる操作が変わる
- 同じ言葉でも部署によって意味が違う
- 例外ルールが多い
- データ整合性を守る必要がある
- 仕様変更が頻繁に起こる
DDDは、こうした複雑さをコードの構造として扱うための考え方です。
主要な登場人物
| 用語 | 意味 | 例 |
|---|---|---|
| ドメイン | 解決したい業務領域 | EC、会計、物流 |
| ユビキタス言語 | 開発者と業務側が共有する言葉 | 注文、出荷、返金 |
| エンティティ | 同一性を持つもの | ユーザー、注文 |
| 値オブジェクト | 値そのものが意味を持つもの | 金額、住所、期間 |
| 集約 | 一貫性を守る単位 | 注文と注文明細 |
| リポジトリ | 集約の保存/取得を表す抽象 | OrderRepository |
| 境界づけられたコンテキスト | 言葉の意味が一貫する範囲 | 販売、配送、請求 |
ユビキタス言語
ユビキタス言語は、チーム内で使う共通語です。
たとえば「キャンセル」という言葉が、注文部門では「注文を取り消す」、配送部門では「出荷を止める」、請求部門では「返金する」を意味する場合があります。このままコードにすると混乱します。
DDDでは、どの文脈でどの言葉を使うかを明確にします。
エンティティと値オブジェクト
| 観点 | エンティティ | 値オブジェクト |
|---|---|---|
| 同一性 | IDで識別する | 値で比較する |
| 変更 | 状態が変わることがある | 原則として不変 |
| 例 | 注文、ユーザー | 金額、メールアドレス |
メールアドレスや金額をただの文字列や数値にせず、値オブジェクトとして扱うと、不正な値を早い段階で防げます。
集約
集約は、一貫性を守る単位です。
注文と注文明細を例にすると、注文明細の合計金額と注文の合計金額は一致している必要があります。このルールを守るため、外部から注文明細だけを勝手に変更できないようにします。
集約を大きくしすぎると更新が重くなり、小さくしすぎると整合性を守りにくくなります。
処理の流れ
注文作成をDDD風に見ると、次のようになります。
| 順番 | 処理 |
|---|---|
| 1 | ユースケースが注文作成を開始する |
| 2 | 商品IDや数量から注文集約を作る |
| 3 | 注文集約が金額や状態のルールを守る |
| 4 | Repositoryが注文集約を保存する |
| 5 | 必要ならドメインイベントを発行する |
ポイントは、業務判断をDB保存処理やControllerに散らばらせないことです。
よくある誤解
DDDは大規模開発だけのもの
戦術パターンを全部使う必要はありません。小さなアプリでも、業務用語を揃える、値オブジェクトを使う、集約を意識するだけで効果があります。
EntityはDBテーブルと同じ
Entityは業務上の概念です。DBテーブルの形に引っ張られすぎると、ドメインモデルが単なるデータ入れ物になります。
DDDはコードだけの話
DDDでは、業務理解、会話、図解、言葉の整理が重要です。コードはその結果です。
まとめ
DDDは、複雑な業務ルールをコードへ反映するための考え方です。
重要なのは、業務の言葉をそのまま設計とコードに反映し、言葉の意味が混ざる場所に境界を引くことです。