DDDのドメイン・サブドメイン・ユビキタス言語・境界づけられたコンテキストを整理する

この記事は [ドメイン駆動設計 #2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ddd-2) の 18日目 です。

前々日は @little_hand_s さんの「[非エンジニアの方に「DDDって何なの？」と聞かれたときの説明](https://little-hands.hatenablog.com/entry/2018/12/17/what_is_ddd)」でした。

# この記事の内容

ドメイン駆動設計（以下、DDD）に登場する、「ドメイン」「サブドメイン」「ユビキタス言語」「境界づけられたコンテキスト」「ドメインモデル」って、どう関連しているのかとか、それぞれの微妙な違いが分かりにくかったり、人によって解釈が異なっていた経験はないでしょうか？

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">IDDD 2章の「問題空間」と「解決空間」がよくわかんないなぁ...<br><br>問題とその解決と言う2つの視点はわかるんだけど、「解決空間とは境界づけられたコンテキストのこと」ってのがわからん。</p>&mdash; Yohei TSUJI (@crossroad0201) <a href="https://twitter.com/crossroad0201/status/1072387043639074816?ref_src=twsrc%5Etfw">2018年12月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この記事では、書籍 「[エリック・エヴァンスのドメイン駆動設計](http://amzn.asia/d/6iK0IFQ)（以下、Evans）」 、「[実践ドメイン駆動設計](http://amzn.asia/d/0pMZiUy)（以下、Vernon）」と、Web上で公開されているいくつかの記事を総合してこれらを整理しようと思います。

# 概念

## ドメインと問題空間／解決空間

![domain_subdomain_bc.png](https://qiita-image-store.s3.amazonaws.com/0/94618/14e9ae89-ebcc-9ef7-0469-4b51623b1c23.png)

### ドメイン

**「ドメイン」** とは、現実世界から抜き出したシステム化対象の業務領域です。

「ドメイン」には「問題空間」と「解決空間」 の2つの見方（ビュー）があります。

> ドメインは、問題空間と解決空間を持っている。
> 問題空間は、解決すべきビジネス戦略上の課題を浮き彫りにするもので、
> もう一方の解決空間は、ソフトウェアをどのように実装してその課題を解決するかに注目するものだ。
> - Vernon 第2章 ドメイン、サブドメイン、境界づけられたコンテキスト / 2.10 実世界におけるドメインとサブドメイン

「問題空間」は *What* と *Why* の観点、「解決空間」は *How* の観点とも言えそうです。

考察や議論をするときにこのビューがごっちゃになりやすいので、今どちらの見方をしているのか？を意識することがDDDの理解を助けるポイントになります。

## 問題空間

**「問題空間」** では解決したいビジネス上の問題や関心事を定義します。

### ユビキタス言語

**「ユビキタス言語」**は、「ドメイン」について語るための語彙（用語集）です。

システムの開発者とドメインエキスパート（業務知識を持っている人）の会話、さらにはドキュメントやプログラムコード、モジュールと言ったソフトウェアを構成する成果物でも統一的に使用される言葉になります。

> ドメインモデルはその共通言語の基盤となれるし、その一方で、チームのコミュニケーションをソフトウェアの実装と結びつけることもできる。
> この言語はチームで行う作業のいたるところに（ユビキタスに）存在できるのだ。
> - Evans 第2章 コミュニケーションと言語の使い方 / ユビキタス言語

### サブドメイン

プロジェクトが扱う「ドメイン」の大きさにもよりますが、一般的に「ドメイン」全体を一気に相手するのは困難です。
考慮しなければならないスコープが広すぎて議論するにも苦労しますし、実装されたソフトウェアも複雑に絡み合った巨大なもの（いわゆる”巨大な泥団子”）になってしまいます。

> 巨大なシステム向けのドメインモデルを完全に統一することは、現実的ではないし、コストにも見合わない。
> - Evans 第13章 モデルの整合性を維持する

そこで、DDDでは「ドメイン」を凝集度の高い複数の「サブドメイン」に分割することでスコープを「サブドメイン」に限定し、このような問題を解決します。

「サブドメイン」には3つの捉え方があります。

* コアサブドメイン[^1]
* 支援サブドメイン
* 汎用サブドメイン

[^1]: 「[CodeZine 実践DDD本 第2章「ドメイン」「サブドメイン」「境界づけられたコンテキスト」を読み解く](https://codezine.jp/article/detail/9744)」では、コアドメインはサブドメインに含めない解釈のようです。

ただし、「支援サブドメイン」か「汎用サブドメイン」かの区別はあまり気にする必要はないと思います。
要は **「コアドメインかどうか」が重要** です。
（そもそも、「支援サブドメイン」と言う呼び方は Evans には登場せず、Vernon 固有の分類のようです）

> ドメインモデルを資産化するには、モデルのきわめて重要なコアを洗練し、アプリケーションの機能を作り出す上で最大限に活用しなければならない。
> - Evans 第15章 蒸留 / コアドメイン

> コアドメインのビジョンやゴールを理解せず、それを支援するためのドメインの範囲も把握できていないようなら、
> 戦略的な利益を得ることなどできないし、落とし穴を回避することもできない。
> - Vernon 第2章 ドメイン、サブドメイン、境界づけられたコンテキスト / 2.10 実世界におけるドメインとサブドメイン

#### コアサブドメイン（コアドメイン）

「ドメイン」の中で最もシステム化する価値の高い領域。
ここがコケたらプロジェクトの存在価値自体ないよね、と言う部分です。

この「コアドメイン」にリソース（資金、優秀なエンジニアなど）を集中することで、早期にビジネス価値を最大化します。
「コアドメイン」だけを実装して価値検証すれば、ビジネスリスクを軽減することもできるでしょう。

> 開発対象のアプリケーションの目的にとって、代表的で中心的なモデルの部分が、コアドメインを構成する。
> コアドメインとは、システム内で最大の価値を付加すべき場所である。
> - Evans 第15章 蒸留 / コアドメイン

#### 支援サブドメイン

「コアドメイン」ではない業務領域。
コアではない領域を別のサブドメインとして切り出すことで、「コアドメイン」をより本質的な部分だけに磨くことができます。

> 業務に不可欠な内容を表しているが、まだコアドメインとはいえないようなモデルのことを、支援サブドメインと呼ぶ。
> - Vernon 第2章 ドメイン、サブドメイン、境界づけられたコンテキスト / 2.8 全体像

#### 汎用サブドメイン

ビジネス上の関心事ではないが、システムを機能させるために必要な領域。
認証・認可など、業務の観点よりシステムの観点から識別されます。

> 設計中のプロジェクトにとって動機となっていない、高凝集のサブドメインを識別すること。
> そうしたサブドメインから汎用的なモデルを括り出して、別のモジュールに入れること。
> - Evans 第15章 蒸留 / 汎用サブドメイン

## 解決空間

**「解決空間」** では、「問題空間」で定義した問題をどう紐解いて解決するか？を定義します。

### 境界づけられたコンテキスト

**「境界づけられたコンテキスト」**は、「ユビキタス言語」が通用する範囲を明確に区切ります。

「ドメイン」の中で使われる言葉には、同じ単語が使われていたとしても

* ドメインエキスパートによって、単語の意味解釈が違う。
* 同じドメインエキスパートでも、話の文脈によって単語の意味解釈が違う。

といったことがありますが、このような意味解釈の違いが「境界づけられたコンテキスト」となり、それぞれのコンテキストで「ユビキタス言語」が方言のように独立して発展・成長していきます。

> 例えば、「商品を販売する」と「商品を仕入れる」と言う業務があり、それぞれのドメインエキスパートがいずれも「商品」と呼んでいたとします。
> 
> 販売業務で関心があるのは商品の売値であったり売れ筋かどうかなどです。
> 仕入業務では仕入値であったり仕入先だったりします。
> つまり、同じ「商品」でも業務によって関心事が違います。
> 
> これを共有の「商品マスタ」のようにすると、一方での変更が他方の業務にも影響してしまいます。
> そこで、販売業務と仕入業務をそれぞれ「境界づけられたコンテキスト」とし、その中で「商品」を定義します。

そして、そのコンテキストの「ユビキタス言語」を使って「サブドメイン」をモデル化します。
よって、「境界づけられたコンテキスト」には、その「ユビキタス言語」を使ってモデル化された「ドメインモデル（後述）」が含まれます。

> 他のコンテキストでは他のモデルが適用されるが、そのモデルとは用語法や概念とルール、ユビキタス言語の方言が異なっている。
> - Evans 第14章 モデルの整合性を維持する / 境界づけられたコンテキスト

また、「境界づけられたコンテキスト」にはそのコンテキストのドキュメントやソフトウェア資産（コード、モジュール）など、あらゆる成果物も含まれます。

> 境界づけられたコンテキストは、この特定のモデルによって駆動されるシステムの持つ、あらゆる側面によって構成される。
> すなわち、モデルオブジェクトや、そのモデルオブジェクトを永続化するデータベーススキーマ、そして予約アプリケーションといったものだ。
> - Evans 第14章 モデルの整合性を維持する / 境界づけられたコンテキスト

そして、「境界づけられたコンテキスト」を1つのチームが担当することで、チームはそのコンテキストのビジネス価値・成果物にオーナーシップを持って取り組むことができるようになります。
このオーナーシップが、ビジネス価値の高いソフトウェアをすばやく構築し、発展させていくための重要な要素になります。

### ドメインモデル

**「ドメインモデル」** は、システムに求められている要件を満たすために「サブドメイン」を分析・抽象化したモデルです。

「サブドメイン」に含まれる概念の中からシステムの関心事だけを選別して分析（静的観点でのモデリング）し、
そのモデルで実現したい業務フローやユースケースを駆動することができるか（動的観点でのモデリング）を検討して作成します。

「ドメインモデル」は文章や図などでも表現されますが、最終的にはプログラムコードとして表現されます。

> モデルとは簡素化である。つまり、当面の問題を解決する上で関連する側面を抽象化し、
> それ以外の詳細を無視することによって行われた、現実に対する1つの解釈なのだ。
> - Evans 第1部 ドメインモデルを機能させる

なお、1つの「境界づけられたコンテキスト」に含む「サブドメイン」は1つだけになるのが理想的です。
（現実的には複数の「サブドメイン」が含まれる形になる場合もあります）

１対１になることで、他の「サブドメイン」と成果物を共有する必要がなくなり、チームをまたいだ調整や合意形成のプロセスから開放されます。

> 各サブドメインを、境界づけられたコンテキストと一対一で対応させるのが、望ましいゴールだ。
> - Vernon 第2章 ドメイン、サブドメイン、境界づけられたコンテキスト / 2.10 実世界におけるドメインとサブドメイン

# 関連とサイクル

上述の概念がどう関連しどういうサイクルでエンジニアリングが進んでいくのか？は、鶏が先が卵が先かな感じですがおおむね下図のような流れになるかなと思います。

![cycle.png](https://qiita-image-store.s3.amazonaws.com/0/94618/251fd9d4-e83d-6529-1b03-07a35a211416.png)

1. 「ドメイン」をビジネス要件の凝集度で「サブドメイン」に分割する。
1. 「ドメイン」および「サブドメイン」の言葉を「ユビキタス言語」として定義する。
1. 「ユビキタス言語」を意味解釈で「境界づけられたコンテキスト」に区切る。
1. 「サブドメイン」を「境界づけられたコンテキスト」で区切られた「ユビキタス言語」を使って、「ドメインモデル」にモデリングする。
1. 「ドメインモデル」へのモデリングで得られた知見を、「ユビキタス言語」にフィードバックする。

とは言え、実際は一方通行で一気に進めるのではなく、相互に行ったり来たりしながら全体をブラッシュアップしていくことを繰り返して「ドメインモデル」と「ユビキタス言語」を継続的に成長させていくことが重要だと思います。

# おわりに

今回、この記事を書くにあたって改めて書籍を読み返したりしてみて、自分自身の理解もあいまいだったなと思わされました。

DDDについては抽象度が高いテーマであることもあって、この記事とは異なる解釈も当然あると思います。
ただ、解釈が異なるとDDDの進行に支障をきたす恐れがあるので、DDDをはじめる際には **プロジェクト／チーム内でどう解釈するかを議論して認識をあわせておく** ことをオススメします。

また、DDDの実践で非常に重要だと思うのは、「境界づけられたコンテキスト」とチームの関係です。

昨今のソフトウェア開発（特に新規サービスの開発）においては、チームがオーナーシップを持てるかどうかがキーだと考えています。
**オーナーシップを持つことで、チームに自律性と責任意識が産まれ、ビジネス価値のあるソフトウェア・ビジネスに勝てるソフトウェアを高速かつ継続的にデリバリーできる** ようになっていくはずです。

DDDの「境界づけられたコンテキスト」を組織やチームとうまく組み合わせることで、オーナーシップを自然発生的に感じられる構造にできるのではないかと思います。

最後にこの記事がDDDの理解と実践の参考になれば幸いです。

# 参考文献

* 書籍 [エリック・エヴァンスのドメイン駆動設計](http://amzn.asia/d/6iK0IFQ)
* 書籍 [実践ドメイン駆動設計](http://amzn.asia/d/0pMZiUy)
* [CodeZine 実践DDD本 第2章「ドメイン」「サブドメイン」「境界づけられたコンテキスト」を読み解く](https://codezine.jp/article/detail/9744)
* [Microservices と DDD - 魔女の一撃](http://s-edword.hatenablog.com/entry/2018/12/04/004525)
* [ユビキタス言語の作り方（ある一つの事例より）](https://qiita.com/tanaka9230/items/f6abcfcfc892bad976d6)
* [Sub-domains and Bounded Contexts in Domain-Driven Design (DDD) - Lev Gorodinski](http://gorodinski.com/blog/2013/04/29/sub-domains-and-bounded-contexts-in-domain-driven-design-ddd/)


<!--
===========================================================================================


エヴァンス本 14章 境界づけられたコンテキストの以下のコラム...

訳書から引用
> コラム ――境界づけられたコンテキストはモジュールではない
>  この問題は混同されることもあるが、動機が異なる別々のパターンなのだ。
>  確かに、2つのオブジェクトの集合が別々のモデルを構成していると認識される場合、そうしたオブジェクトはほとんど常に別個のモジュールに置かれることになる。
> そうすることで、別々の名前空間（異なるコンテキストには不可欠）と何らかの境界が与えられる。
>  しかし、モジュールは1つのモデルの中で複数の要素を構成するものでもあり、別のコンテキストに対して、必ずしも意図を伝えるものではない。
> 境界づけられたコンテキストの中でモジュールが個別の名前空間を作成することにより、実は、偶発的に発生するモデルの断片化が見つけにくくなっているのだ。

原著から引用
> This issue sometimes gets confused with the motivations for MODULES.
>  True, when it is recognized that two sets of objects make up different models they are typically placed in separate MODULES,
> and this does provide different name-spaces that allow them to compile even if they have name overlaps.
>  But this is just an implementation mechanism for code separation of different models.
> This issue is preceded by the fundamental problems, recognizing model differences and deciding what to do with them.
>  Furthermore, MODULES are also used to organize the elements within one model, so they don’t communicate an intention to separate models.
> The separate name-spaces they create can actually make it harder to spot accidental model divergences.
> While technical tools can help us communicate and implement conceptual issues, they don’t solve our conceptual problems.

原著の和訳
> この問題は、MODULESの動機と混同されることがあります。
>  実際には、2つのオブジェクトセットが異なるモデルを構成することが認識されると、それらは通常、別々のMODULESに配置され、
> 異なる名前空間を提供し、名前の重複があってもコンパイルできます。
>  しかしこれは、異なるモデルのコード分離のための実装メカニズムです。
> この問題には基本的な問題が先行しています。モデルの違いを認識し、モデルの違いを判断することです。
>  さらに、MODULESは、1つのモデル内で要素を編成するためにも使用されるため、モデルを分離する意図はありません。
> 別々の名前空間は、実際にはモデルの相違を突き止めるのを困難にします。技術的ツールは、概念的な問題を伝達して実装するのに役立ちますが、概念的な問題は解決しません。

----

## https://codezine.jp/article/detail/9744

![9744_001_s.gif](https://qiita-image-store.s3.amazonaws.com/0/94618/1ed037da-1572-8957-dd99-3aa5b2fa8228.gif)

広義のドメインには「分析対象となる問題領域」と「事業課題の改善に取り組む解決領域」が含まれています。そして、分析対象となる問題領域が「ドメイン」であり、その問題や課題に取り組む解決領域が「境界づけられたコンテキスト」となります。

ドメインの課題を解決する部分を「境界づけられたコンテキスト」と呼びます。IDDDでは、1つの「コアドメイン（もしくはサブドメイン）」に、1つの「境界づけられたコンテキスト」が対応している状態が最適だとされています。ただし、現実の（レガシー）システムでは、複数のドメインに対して1つの境界づけられたコンテキストしか存在しないケースも多々存在します。

-->