DDDを一言でいうと
DDDはDomain-Driven Designの略で、日本語ではドメイン駆動設計と呼ばれます。難しそうな名前ですが、考え方の中心はとても実務的です。システムを画面やデータベースから考え始めるのではなく、業務そのものの意味、ルール、言葉を中心にして設計する方法です。
ここでいうドメインとは、システムが扱う業務領域のことです。たとえばネットショップなら、注文、支払い、在庫、配送、返品といったものがドメインに含まれます。DDDでは、これらを単なるテーブル名や画面名として扱うのではなく、業務上の意味を持つ重要な概念として扱います。
実務で長くシステムを見ていると、保守しにくくなるシステムには共通点があります。最初はきれいに作ったつもりでも、業務ルールが画面処理、SQL、バッチ、APIに少しずつ散らばり、数年後には「本当の仕様がどこに書いてあるのか分からない」状態になってしまうのです。DDDは、この問題に対する有力な考え方の一つです。
従来型の開発との違い
多くの業務システムでは、要件定義の早い段階で画面一覧、帳票一覧、テーブル一覧を作ります。これは決して間違いではありません。画面やDBは、見積もりやスケジュール管理に必要だからです。
しかし、業務が複雑なシステムでは、それだけでは不十分です。たとえば「注文をキャンセルする」という処理を考えてみます。単純に注文テーブルのステータスをキャンセルに更新すればよいように見えますが、実際には、発送前かどうか、支払い済みかどうか、在庫を戻す必要があるか、返金処理が必要かといった判断が関係します。
画面中心やDB中心の設計では、こうした判断が各処理に埋もれやすくなります。一方DDDでは、「注文をキャンセルする」という業務操作を中心に考えます。その操作にはどのような条件があるのか、どの状態から実行できるのか、実行後に何が変わるのかを明確にします。
| 観点 | 従来型で起きやすい考え方 | DDDで重視する考え方 |
|---|---|---|
| 設計の起点 | 画面、DB、機能一覧 | 業務概念、業務ルール、言葉 |
| 処理の捉え方 | ステータスを更新する | 注文をキャンセルする |
| 仕様の置き場所 | 画面処理やSQLに分散しやすい | ドメインモデルに集約する |
| 変更への対応 | 修正箇所を探す必要がある | 業務ルールの中心を追いやすい |
この違いは、開発初期には小さく見えます。しかし運用が始まり、仕様変更や例外対応が増えるほど、大きな差になります。
要件定義で最初にやるべきこと
DDDを取り入れる場合、要件定義では機能一覧を作る前に、業務の言葉を丁寧に確認します。関係者が同じ言葉を同じ意味で使っているとは限らないからです。
たとえば「取消」「キャンセル」「返品」「無効」という言葉がある場合、それぞれは同じ意味でしょうか。注文前の取消と発送後の返品では、業務上の意味も、会計上の扱いも、在庫への影響も違うかもしれません。この違いを曖昧にしたまま設計に進むと、後工程で大きな手戻りになります。
DDDでは、関係者が共通して使う言葉をユビキタス言語と呼びます。これは単なる用語集ではありません。会議で使う言葉、設計書に書く言葉、プログラム上のクラス名やメソッド名まで、できるだけ同じ言葉でそろえるという考え方です。
要件定義では、次のような問いを繰り返します。
- この業務で重要な対象は何か
- その対象はどのような状態を持つのか
- どのタイミングで状態が変わるのか
- その操作を実行できる条件は何か
- 関係者の間で言葉の意味にズレはないか
この確認を丁寧に行うことで、単なる機能一覧では見えない業務の本質が見えてきます。
設計工程では何を作るのか
要件定義で業務の言葉とルールが見えてきたら、設計工程ではそれをドメインモデルとして整理します。ドメインモデルとは、業務の重要な概念とルールをソフトウェア上で表現したものです。
たとえば注文業務であれば、注文、注文明細、顧客、支払い、配送、在庫といった概念が候補になります。ただし、ここで注意すべきなのは、ドメインモデルはDBテーブルの写しではないという点です。テーブルはデータを保存するための構造ですが、ドメインモデルは業務を表現するための構造です。
注文モデルであれば、注文番号や注文日を持つだけでは不十分です。注文を確定する、キャンセルする、発送済みにする、返品を受け付けるといった業務上の振る舞いも重要です。DDDでは、データとルールをできるだけ近い場所に置くことで、仕様の見通しを良くします。
また、関連するモデルをどの単位でまとめるかも重要です。DDDでは、整合性を守る単位を集約と呼びます。注文と注文明細のように、一緒に変更されるべきものは、注文を中心とした集約として扱うことがあります。これにより、注文明細が0件の注文は確定できない、キャンセル済みの注文は明細を変更できない、といったルールを守りやすくなります。
DDDの利点
DDDの大きな利点は、業務ルールの居場所が分かりやすくなることです。業務システムでは、リリース後の変更が必ず発生します。料金体系が変わる、承認条件が変わる、例外対応が増える。このとき、ルールが画面やSQLに分散していると、修正漏れや不整合が起こりやすくなります。
DDDでは、重要なルールをドメインモデルに集めるため、変更時に確認すべき場所が明確になります。もちろん、DDDを使えばすべての変更が簡単になるわけではありません。しかし、少なくとも「業務上の重要な判断はどこにあるべきか」という設計方針が明確になります。
もう一つの利点は、業務担当者と開発者の会話がかみ合いやすくなることです。開発者が「ステータス更新処理」と呼び、業務担当者が「注文確定」と呼んでいる状態では、会話のズレが生まれます。DDDでは、業務の言葉を設計に反映するため、認識違いを早い段階で発見しやすくなります。
DDDが向いている場面と向いていない場面
DDDは万能ではありません。単純なマスタ管理や、登録、検索、更新、削除が中心の小さなシステムに厳密なDDDを持ち込むと、かえって設計が重くなることがあります。
一方で、業務ルールが多く、状態遷移が複雑で、長期間にわたって改善を続けるシステムには向いています。特に、注文、契約、請求、審査、予約、在庫、ワークフローのように、判断条件や例外が多い領域では効果を発揮しやすいです。
実務では、システム全体をDDDで作る必要はありません。重要なのは、複雑で変更が多く、業務価値の中心となる部分にDDDの考え方を適用することです。単純なマスタ管理は従来型のCRUDで作り、業務ルールが濃い部分だけドメインモデルを丁寧に設計する。このくらいの割り切りが、現場では現実的です。
まず小さく始める
DDDを始めるとき、最初から専門用語をすべて使いこなそうとする必要はありません。まずは、要件定義で業務用語を整理し、重要な状態変化と業務ルールを書き出すところから始めるのがよいです。
具体的には、用語集、業務ルール一覧、状態遷移図、主要なユースケース一覧を作ります。これだけでも、画面やDBだけを見ていたときより、設計の解像度は大きく上がります。
DDDは、特別なフレームワークや言語に依存するものではありません。JavaでもC#でもPHPでも考え方は使えます。大切なのは、業務の言葉で考え、その言葉を設計と実装に反映することです。
システム開発で本当に難しいのは、コードを書くことだけではありません。業務を正しく理解し、変化に耐えられる形に整理することです。DDDは、その難しさに正面から向き合うための実践的な設計思想だと言えます。