TL;DR
- 問題空間と解決空間を区別し、問題空間のドメインから必要な側面だけを取り出して、解決空間の境界づけられたコンテキストに写す。
- コンテキストの区別は職人芸だが、ガイドラインがある。コンテキスト間の関係はコンテキストマップで示し、最も価値のあるコアドメインから実装する。
内容
問題空間と解決空間
特定の問題を解決するには、関連する情報だけを取り入れるべきである。そのためには、問題空間と解決空間を区別し、2 つを別のものとして扱う。具体的には、問題空間のドメインのモデル(ドメインモデル)を作り、ドメインの必要な側面だけを取り出して解決空間に作り直す。
解決空間では、問題空間のドメインとサブドメインが、境界づけられたコンテキストに対応付けられる。それぞれの境界づけられたコンテキストは、それ自体が小さなドメインモデルである。
サブシステムなどの言葉ではなく「境界づけられたコンテキスト」と呼ぶのは、解決手段を設計するときに、コンテキストと境界を意識することに集中するためである。
- コンテキストを意識する理由: それぞれのコンテキストは、解決手段の中の何らかの専門知識を表している。コンテキストの中では共通の言語が使われ、設計は一貫している。しかし、コンテキストの外に持ち出された情報は、混乱を招いたり役に立たなかったりする。
- 境界づける理由: 現実世界のドメインの境界は曖昧である(ドメインをサブドメインに分割する)。一方、ソフトウェアでは、複雑さを減らして保守性を高めるために、サブシステム間の結合を減らし、それぞれが独立して進化できるようにしたい。そのために、サブシステム間に API を設けたり、共有コードのような依存関係を避けたりといった標準的な手法を使う。
問題空間のドメインと解決空間のコンテキストは、常に一対一とは限らない。1 つのドメインが複数のコンテキストに分かれることも、既存システムとの統合などで複数のドメインが 1 つのコンテキストにまとめられることもある。
モデルを実装するとき、境界づけられたコンテキストはソフトウェアのコンポーネントに一対一で対応するので、どう分割しても、それぞれのコンテキストに明確な責任を持たせることが重要である。そのコンポーネントは、別の DLL、独立したサービス、あるいは単なる名前空間として実装できる。
コンテキストを正しく区別する
DDD で最も重要かつ難しいのは、境界づけられたコンテキストを定義することである。理論ではなく職人芸の世界だが、次のガイドラインがある。
- ドメインエキスパートの声に耳を傾ける。 同じ言語を共有し、同じ問題に取り組んでいるなら、同じコンテキストで作業している。
- 既存のチームや部門の境界に注目する。 企業がドメインとサブドメインをどう考えているかの手がかりになる。ただし、同じ部署の人がばらばらに仕事をすることも、異なる部門の人が密接に協力することもある。後者は同じドメインで仕事をしていると考えられる。
- 「境界づけられた」の部分を忘れない。 曖昧すぎる境界は境界ではない。「良い塀が良い隣人を作る」。
- 自律性を目指して設計する。 1 つのコンテキストにドメインエキスパートのグループが 2 組関わると、設計が進化する過程でそれぞれが別の方向に引っ張る可能性がある。そこで、コンテキストを分けて個別に進化できるようにしたほうがよい。自律性を求めるのは、性能のためではなく、一定の可用性とサービスを約束できるようにするためである。どうしても自律性を確保できないときは、相手のサービスを信頼し、問題が起きても対応できるようにしておく。
- 摩擦のないビジネスワークフローを目指して設計する。 ワークフローが複数のコンテキストとやり取りし、それらにたびたび止められたり遅らされたりするなら、設計が煩雑になってもワークフローが滑らかになるようにコンテキストのリファクタリングを検討する。設計の「純粋さ」よりも、ビジネスと顧客の価値に焦点を当てるべきである。
また、ビジネス要件の変化に合わせて、モデルを時間とともに進化させる必要がある(第13章 Evolving a Design and Keeping It Clean)。
コンテキストマップの作成
コンテキストを定義したら、設計の詳細に立ち入らずに、コンテキスト間のやり取りを伝える方法が必要になる。DDD ではこれをコンテキストマップと呼ぶ。コンテキストマップの目的は、すべての詳細を把握しなくてもシステムの全体像を示すことである。
やり取りする 2 つのコンテキストは、交換するメッセージの共有フォーマットに合意する必要がある。一般に上流側のコンテキストがフォーマットに大きな影響力を持つが、レガシーシステムを使っている場合など、下流側に柔軟性がないこともある(第3章 A Functional Architecture)。システムが複雑なら、特定のサブシステムに焦点を当てた小さなマップを複数作る。
最も重要なコンテキストに焦点を当てる
ビジネスの観点から、他より重要なドメインがある。これをコアドメインと呼ぶ。コアドメインを見つけるのは難しく、思いもよらないものがコアドメインのこともある。何がコアドメインであれ、重要なのは優先順位を付けることと、すべてのコンテキストを同時に実装しようとしないことである。最も価値のあるコンテキストに焦点を当て、そこから広げていく。
ほかに、必要不可欠だがコアではない支援ドメインや、企業に固有ではない汎用ドメインもある。
キーワード
自分の理解
そもそも DDD は、ビジネスに焦点を当てる開発手法である。設計の純粋さよりビジネスと顧客の価値を優先するのは、その考え方に沿っている。