ドメイン駆動設計は何を解決しようとしているのか[DDD]

[ドメイン駆動設計の定義についてEric Evansはなんと言っているのか](http://little-hands.hatenablog.com/entry/2017/09/27/014403)
の記事の中で、EricEvansのドメイン駆動の定義を引用して以下のように和訳しました。


1. ドメインの中核となる複雑さと機会に焦点を当てる
1. ドメイン専門家とソフトウェア専門家のコラボレーションでモデルを探求する
1. 明示的にそれらのモデルを表現するソフトウェアを書く
1. 境界付けられたコンテキストの中のユビキタス言語で話す

この中で、重要なポイントが明示されていませんでした。

***定義にある4点のようなことを、なぜやる必要があるのか？*** ということです。

つまり、***ドメイン駆動設計は、一体何を解決しようとしているのでしょうか？*** 


### ドメイン駆動設計は何を解決しようとしているのか
DDDはソフトウェア開発手法の一つです。  
なのでまず、ソフトウェア開発の目的について考えてみましょう。

人々はなぜ、ソフトウェアを開発するのでしょうか？  
それは、***ソフトウェアを適用する対象の何らかの問題を解決するため***と言えるでしょう。

この「ソフトウェアを適用する対象」を「ドメイン」と呼びます。  
ソフトウエアは特定のドメインから生まれ、そしてそのドメインと深く関わっています。

それでは、DDDでは、ソフトウェア開発に対してどのようなアプローチをするのでしょうか。  
[ドメイン駆動設計の定義についてEric Evansはなんと言っているのか](http://little-hands.hatenablog.com/entry/2017/09/27/014403)でも参照した[DDD Reference](http://domainlanguage.com/ddd/reference/)の冒頭に、こういう記述があります。

* Many projects do modeling work without getting much real benefit in the end. The patterns of DDD distill successful practices from projects where dramatic benefits have come from modeling. 
* 多くのプロジェクトは、***モデリングを行っても最終的に大きな利益を得られないまま終わります。*** DDDは、***モデリングから劇的な利益***を得られたプロジェクトから、成功するパターンを抽出します。

つまり、DDDは

* ***ドメインモデリングによって***ソフトウェアの価値を高める

というアプローチをとっています。

それでは、モデリングから利益を得る、とはどういうことでしょうか？


### 「モデリングから利益を得る」とは
まず、モデルの定義について確認しましょう。  
EricEvansの定義によると、***「問題解決のために、物事の特定の側面を抽象化したもの」***です。  
現実世界をそのままソフトウェアにすることはできません。問題解決に適した形で抽象化する必要があり、その成果物がモデルです。

具体的な例で考えてみましょう。

#### 例：日報のモデリング
たとえば紙で日報を書く業務があり、これを  
「日報を物理的に置いて置く場所がないので、オンラインで完結させたい」  
という問題を解消するためにシステム化するとします。

現実世界では非常に多くの情報があります。  
```
日報を書いた人の名前、日報の日付、内容、
日報を書く冊子のページ数、値段、材質、購入者、
日報を仕舞う場所、日報を書くペン、場所、時間・・・
```
といったように、切り出し方によって無限の情報があります。

前述の通りこの全てをソフトウェア化に落とし込むことは不可能ですし、その必要もありません。  

そこで、今回のソフトウェアでは、先程の問題を解決するためには必要な情報として以下のように定義しました。

```
日報を書いた人の名前、日報の日付、内容
```

これがモデルです。

#### 良いモデルとは
それでは、良いモデルとはなんでしょうか？  
「問題解決のために、物事の特定の側面を抽象化したもの」という定義から考えると、その***問題を解決できるのが良いモデル、できないのがよくないモデル***です。

では問題解決できないモデルとはどんなものでしょうか？日報の例を考えて見ましょう。

日報の業務(以下、ドメイン)について分析をしていると、  
実は日報は上長からフィードバックコメントのやりとりに使用されており、これは今回のシステム化でなくすわけにはいかないということがわかりました。

しかし、今の日報のモデルには「日報を書くひと、日報の日付、内容」という情報しか持っていません。これではフィードバックという概念を表現することができず、ドメインに存在する「日報をオンラインで完結させたい」という問題を解決できません。

つまり、先程のモデルは不十分で、良くないモデルということになります。

それでは、良いモデルを作り、モデリングから利益を得るために、はどうしたら良いのでしょうか？

### モデリングから利益を得るためのアプローチ
日報の事例からもわかるとおり、問題を解決するためには、ドメインについて正しく理解し、モデルに反映する必要があります。  
さらに、ソフトウェアとして価値を出すためには、モデルからソフトウェアへの反映が必要になります。

よって、DDDでは大きく分けて以下の図の2つのアプローチを行います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/30489/604aeae7-c3ef-4ef1-5817-863ac0016f8d.png)

#### 1.ドメインについての理解を深め、モデルを改善し続ける
先述の例で、ドメインについての理解がなければ、正しく問題を解決できないとがわかりました。では、ドメインについて理解するにはどうするのがよいでしょうか？

そう、***ドメインに詳しい人に聞くしかない***ですね。

聞く頻度はどの程度が良いでしょうか？  

モデリングして、ソフトウェアをリリースしてからフィードバックを得ればよいでしょうか。それよりは、***モデルを作った段階で認識を合わせた方が良い***ことは想像に難くありません。    
モデルを作成、更新したら、その都度認識を合わせた方が手戻りが少なくなりますし、モデルについて早期に改善できる可能性が高まるでしょう。  

つまり、ドメインへの理解を深めるには、  
***ドメインに詳しい人からできるだけ高い頻度でモデルに対するフィードバックをもらうことが重要***ということです。

##### 定義されたアプローチ
DDDではこのアプローチに名前をつけて定義しています。

ドメインに詳しい人を***"ドメインエキスパート"***と呼び、ドメインエキスパートと同じ言葉を使い、一緒にモデルを"探求"していくことを原則としています。

この時、認識齟齬の防止や、ことなる言葉の変換コストを下げるためにドメインエキスパートや開発者全員が「同じ言葉を使う」ことも同様に原則としており、その言葉を***"ユビキタス言語"***と呼びます。  

また、「全世界共通のモデル」「会社全体で共通のモデル」というのは現実的ではないので、このモデルを適用する範囲を決めよう、という発想からそれを明示するのが***"境界づけられたコンテキスト"***です。

この辺りの詳しい解説はこちらの記事をご参照ください。  
[境界づけられたコンテキスト 概念編](http://little-hands.hatenablog.com/entry/2017/11/28/bouded-context-concept)  
[境界づけられたコンテキスト 実装編](http://little-hands.hatenablog.com/entry/2017/12/07/bouded-context-implementation)

#### 2.モデルを継続的にソフトウェアに反映する
モデルを継続的に改善し続けることになれば、自ずとその変更をソフトウェアに反映し続ける必要が発生します。  
これに対応できるということは、***ソフトウェアにとっては大きな要求***です！

通常モデルはDBに近いので、コストを考えて変更が極力避けられがちなものです。アーキテクチャレベルでしっかりした用意がなければ、この要求に対応することは難しくなります。

これにたいして、DDDでは

* モデルをそのまま表現したソフトウェアを書く
* 実績のあるDDDのデザインパターンを使用する

というアプローチを提唱しています。  

##### モデルを表現したソフトウェアを書く
モデルとソフトウェアのマッピングが明らかになるように、  
***モデルをできる限りソフトウェア上に表現する***ことを目指します。  
具体的な事例は[モデルでドメイン知識を表現するとは何か](http://little-hands.hatenablog.com/entry/2017/10/04/201201)の記事で紹介しているのでご参照ください。


これは現実的な理由によるものです。  

コードとモデルに乖離があると、モデルが複雑になる程そのマッピングを理解しにくく、頻繁な変更を反映するが難しくなります。  
また、モデルの情報をドキュメントに記述しようとしても、ドキュメントは往往にして古くなるものであり、モデルの知見が反映され損なったり、間違った状態で伝わる可能性が高くなります。

先述のユビキタス言語という概念の"ユビキタス"とは"In everywhere"という意味であり、ドメインエキスパートの発言、開発者の発言、そして***"ソフトウェアの中でも"***という意味が込められています。

##### 実績のあるDDDのデザインパターンを使用する
いわゆる"戦術的DDD"として知られているのがまさにこの辺りです。  
頻繁なコード修正に耐えうるには、かなり高いメンテナンス性が求められます。そのために、色々なプロジェクトを通じて導き出された、***凝集度の高いデザインパターン***として、エンティティやレポジトリなどが定義されています。

DDDのメリットとして一般に認識されている(と思われる)、  
***「メンテナンス性が高いコードが書ける」というのは、実は一番の目的ではなかった***のです。  
有名なエンティティなどのパターンは、目的を達成するために生み出された副産物だった、というのが正しい位置付けでしょう。

余談になりますが、戦術的DDDだけ導入するパターンを"軽量DDD"と呼ぶことがあります。それは「頻繁なモデルの変更にも耐えられるような良い設計だけ取り入れる」と考えると、そこだけでも意味はあることだと考えられると個人的には思います。  
ただ、どうしても思想のベースにはモデルというものがあるので、そこを抜きにして考えるとどこかにしわ寄せが行くことになるとは思います。

### まとめ
DDDについて、そもそもなぜやるのか？ということについては意外と掘り下げられる機会は少なかったのではないでしょうか。  
ここについてまず理解することで、DDDで定義されているアプローチについて形だけなぞるのではなく、意図を組んだ上で取り組むことができるようになるのではないかと思います。

### もっと詳しく知りたい方は

初めてDDDを学ぶ方、もしくは実際に着手して難しさにぶつかっている方向けの書籍を出しました。

[ドメイン駆動設計 モデリング/実装ガイド](https://little-hands.booth.pm/items/1835632)


迷子になりがちな「DDDの目的」や「モデル」の解説からはじめ、
具体的なモデリングを行い実装まで落とす事例を元に、DDDの魅力や効果を体感することを目指します。

この本の「第1章 DDD概要」では、この記事の内容をさらに詳細に解説しています。よろしければお求めください。


【2021/10/30新刊】

DDD解説書の新刊を執筆しました。
重要トピック「モデリング」「集約」「テスト」について詳細に解説し、その他のトピックでは頻出の質問への回答と具体的なサンプルコードをふんだんに盛り込みました。現場で実践して、困っていることがある方はぜひこちらもご覧ください。

https://little-hands.booth.pm/items/3363104

Twitterでも、DDDに関して発信したり、「質問箱」というサービスを通じて質問を受け付けています。こちらもよろしければフォローしてください。

[@little_hand_s](https://twitter.com/little_hand_s:title)


また、YouTubeで[10分でわかるDDD動画](https://www.youtube.com/playlist?list=PLXMIJq1G-_66F9woQpidJfe4HHCFxdXaA)シリーズをアップしています。概要を動画で理解したい方はこちらもどうぞ。チャンネル登録すると新しい動画の通知を受け取ることができます