ドメイン駆動設計について学習したのでまとめ

#はじめに

この記事では、私がドメイン駆動設計(DDD)について学習した内容を、噛み砕いてまとめたものです。
至らぬところがありますので、どうかご容赦ください。

まずは、ドメイン駆動設計とはそもそもなにか、というところを扱いたいと思います。

#ドメイン駆動設計とは

まずはじめに、ドメイン駆動設計とはどう言う意味なのでしょうか。[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88)には、次のように説明されています。

> ドメイン駆動設計（英: Domain-driven design, DDD）とはソフトウェアの設計手法であり、「複雑なドメインの設計は、モデルベースで行うべき」であり、
また「大半のソフトウェアプロジェクトでは、システムを実装するための特定の技術ではなく、ドメインそのものとドメインのロジックに焦点を置くべき」であるとする。
この名称は、 Eric Evans が同名の著作で用いた。

うーん、これだけ聞いてもなんだか抽象的でまだわかりにくいですね。**ドメイン**と**モデル**という言葉をもう少し噛み砕いて考えてみましょう。

##ドメイン
ドメインとは、*業務の関心事*だったり*ビジネスルール*だったりと言われています。

もう一つ段階は進みましたが、まだまだ抽象の域を抜け出せておりません。
ではもう一歩、今度は視点を大きく変えて考えてみましょう。

そもそも、私達がソフトウェアを開発する理由はなんでしょうか。
本来の目的は、**現在行っている業務のプロセス**をソフトウェアに任せることによって、効率化したりすることです。

そう、この現在行っている業務こそが**ドメイン**と呼ぶ存在です。

また、ドメインにはいくつかの**サブドメイン**に分割されます。
現実の業務を一つにまとめようとするには、あまりにも大きすぎるからです。

そして、サブドメインの中には**コアドメイン**が存在します。
コアドメインは、文字通り業務の核となるべき存在です。**業務の成功には、必要不可欠で、コアドメインに特化**した戦略を立てます。

コアドメインは、通常その業務がソフトウェア化されるかどうかに関わらず、存在している業務だとされています。

また、コアドメインはそのアプリケーションによって変化します。
あるアプリケーションにとってはコアドメインとなる存在が、別のアプリケーションから補助的なサブドメインとして使用されることがあるのです。

###境界づけられたコンテキスト
まず。コンテキストの意味から見ていきましょう。
[e-Words](http://e-words.jp/w/%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88.html)

>コンテキストとは、文脈、前後関係、事情、背景、状況などの意味を持つ英単語。ITの分野では、利用者の意図や状況、環境などの総体を表したり、同じ処理や記述でも状況に応じて動作などが異なる場合に、その選択基準となる判断材料や条件などを指す場合が多い。

具体的には、例えば`book`という英単語は出版社コンテキストでは`本`の意味で扱われますが、おそらく旅行会社コンテキストでは`予約する`という意味で扱われるでしょう。

このように、複数のコンテキスト間で使用される用語の意味も大きく変わるため**モデルが適用されるコンテキストを明示的に定義する**必要があります。

一つの巨大なモデルに複数のコンテキストがあるなら、チームで互いの用語に矛盾が生じ、混乱が生じることでしょう。

##モデル
ドメインとは、大まかに業務のプロセスだということがわかりました。
さて、業務プロセスをソフトウェア化するのが目的だと前項で述べました。
当然のことながら、**ドメインをソースコードの中に落とし込む**必要があります。
実際の業務ルールをロジックとして埋め込むのです。

ここで問題が生じます。**ドメインは、たいてい複雑で私達開発者が通常理解できる代物ではありません。**

そういったロジックをコードに直接埋め込んだらどのようなことが起きるかは容易に想像がつくでしょう。
技術には問題ないにも関わらず、複雑なビジネスロジックに耐えきれず、修正や拡張は困難になることでしょう。

そこで、ドメインを抽象化したものを、モデルとして構成します。
また、モデルは業務の正確な意味を捉えているでしょう。
モデルは抽象化することによって現実の複雑さに対応するのです。

モデルは、そういった**複雑なドメインを閉じめた**層です。
モデルにドメインを閉じ込めたら、**モデルはそれがアプリケーションコードに漏洩しないように責務を負います。**

###ドメインモデル貧血症
一方、モデルが存在するもののアプリケーションコードにドメインが漏れ出しているとしたら**ドメインモデル貧血症**が疑われます。

具体的には、publicな*ゲッター*や*セッター*のみで構成されていたり、あるいはMVCのフレームワークにおいてモデルがデータベースとの接続口と考えられているなど**ビジネスロジックがほとんど含まれていない単なる属性と値を保持するオブジェクト**のことを指します。

こうなるとモデルはデータを提供するだけとなります。これでは、まったくもってドメインモデルの利益を享受できません。

結局アプリケーションコードはドメインに汚染されてしまっているのですから。

##モデリング
ドメインとモデルについて学びました。

モデルの重要さを学んだところで、ドメイン駆動設計のコアな部分に気が付きましたか？
そう、**いかに現実のドメインをモデリングするか**です。

この仕事は、我々開発者だけでは手におえませんから、**ドメインエキスパート**との連携が不可欠です。
ドメインエキスパートと会話をして、専門知識について理解する必要があります。

また、ドメインエキスパートとの会話は私達開発者だけでなく、双方にとってもメリットがあります。
ドメインエキスパートもまた業務についての会話をする中で自分が何を知ってて何を知らなかったのか気づくきっかけになります。

きっと業務改善の手がかりとなることでしょう。

###ドメインエキスパート
ドメインエキスパートとは、業務について最も知識の深い人を指します。
通常は、アプリケーションの開発に携わない、クライアントの立場にいることでしょう。

しかし、ドメインエキスパートも同じチームの一員であることを忘れてはいけません。

###ユビキタス言語
ユビキタス言語は、開発者とドメインエキスパートとの間で橋渡しをする共有された言語です。
開発者とドメインエキスパートとの間では、それぞれが**専門用語**を持っていているため、しばしばそれによって会話が阻害されてしまいます。

そこで、チームの共通の言語として使われるものが**ユビキタス言語**です。

ちなみに、ユビキタス自体の意味は次の通りです。

>ユビキタス (英: ubiquitous) は、遍在（いつでもどこでも存在すること）をあらわす言葉。


https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%93%E3%82%AD%E3%82%BF%E3%82%B9

ユビキタス言語がドメイン駆動設計の重要な概念だと言えます。

また、ユビキタス言語は業務の範囲(**境界づけられたコンテキスト**)によっても意味が異なります。

##リファクタリング
ドメインのモデリングは一度設計してら終わりではありません。
小さなリファクタリングを重ねる中で、**的確なモデル**を発見することが目的です。

最初に作られるモデルは、浅い知識に基づいたものであるため、有益なモデルではないことがほとんどでしょう。
イテレーションの中で、知識を身に着けていきモデルの価値は高まっていきます。

しかし、**深いモデル**を得るためには**ドメインエキスパートの主要な関心事**を捉える必要があります。

ドメインエキスパートの使う言葉に耳を傾けるのです。
ドメインエキスパートから、以下のような兆候が見られたら、それはモデルにとって有益になりえる概念の手がかりとなります。

- なにか複雑なものを簡潔に述べている。
- ドメインエキスパートに言葉の選び方を正される。
- 開発者が特定のフレーズを使った時に、ドメインエキスパートの困惑した表情が消える。
- ドメインエキスパートが設計のどこにもない語彙を使用している。


#まとめ

- **ドメイン**は**現実の業務プロセス**のことを指す。
- ドメインをうまく**モデリング**することが必要
- モデリングをうまくするために、**ドメインエキスパート**をチームの一員として協力する。そのためには**ユビキタス言語**が不可欠

#参考文献
[エリック・エヴァンスのドメイン駆動設計](https://www.amazon.co.jp/dp/B00GRKD6XU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[実践ドメイン駆動設計](https://www.amazon.co.jp/dp/B00UX9VJGW)
[ドメイン駆動設計 基本を理解する](https://www.slideshare.net/masuda220/ss-59756718)
[ドメイン駆動設計 失敗したことと成功したこと](https://www.slideshare.net/biglobe-developers/ss-116671399)
[ドメインモデル貧血症](https://bliki-ja.github.io/AnemicDomainModel/)
[IDDD本から理解するドメイン駆動設計](https://codezine.jp/article/corner/655)
[Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.amazon.co.jp/dp/4048930656)