ドメインモデルで設計上の問題を解決する

実装、使用する言語の種類、選択するデータベース構造などにばかり気を取られていると、本来の目的である「ユーザーにとって最も実用的、有用、人間工学的なソリューションにするにはどうすればよいか」を忘れてしまいます。

実際、コードはそれ自体が目的ではなく、ユーザーに提供するソリューションを実現するための手段であることを心に留めておくことが重要です。そのためには、開発者が課題を理解し、その解決策を使う人のニーズを常に念頭に置かなければなりません。
クライアントが満足し、修正や変更が少なくて済むので、あなたの時間も節約でき、面倒なやりとりも減り、そして何より不満が減るのです。😎

>なるほど、わかりました! ユーザーを満足させたい。でも、どうしたらいいんだろう？

成功の可能性があるのは、ドメイン駆動設計を用いて製品を作る関係者と協力して、**ドメインモデル**を作成し、利用することである。

## ドメインモデルを発見

ドメインモデルとは、顧客が求めるソリューションを実現するために、**全員が理解する**必要のある**重要な要素**を概念的に表したものです。プログラムの根幹を成す、ステークホルダーと開発者の双方が理解できるような考え方と考えれば良い。

> 重要な要素とは？

最後に観た映画のことを思い出してみてください。誰かに向けて要約するとしたら、何を言って、何を省きますか？簡単に言うと、話をすれば、*重要な要素*です。

逆に、省いてしまうと重要度が下がる、いわゆる*マイナー要素*です。主人公や登場人物は重要です。乗り越えなければならない障害もそうです。キャラクターがタトゥイーンに行かなければならないことも。しかし、彼がホワイトのジャケットを着ていることはマイナー要素です。 この重要な要素の集まりが、あなたのドメインです。

あなたの映画が続編を持つ場合は最初のドメインの主要な要素にいくつかの要素が追加されます。しかし、これはまったく新しい話なので、いくつかの要素は別にしなければならない。別ドメインになります。

>うわー、2分くらい座ろうか？
>ドメインモデルには、複数のドメインがあり得るということですか？

複雑なドメインモデルの場合、異なる要素を別々のドメインにグループ化することになります。これを**境界付きコンテキスト**と呼ぶ（英語で**boundedcontext**）。

>しかし、その仕組みはどうなっているのでしょうか？

ここでは、よくご存じの「教室」を例に挙げます。例えば、学校向けのソフトウェアを書くとしましょう。

始める前に、すでにクラスの仕組みはわかっているはずです。簡単でしょう？ある日、ある部屋で行われる。授業には担当の先生がいて、その授業を受ける生徒もいます。宿題、評価、テスト、成績は記録されなければなりません。これらのインフラはすべて、あなたのプログラムで管理されなければなりません。

しかし、すべてが準備できたと思った矢先、やりとりの中で誰かが金銭的な面を持ち出してきたのです。先生への支払いや、部屋の電気代も必要だ。そうすると、同じ概念（生徒、先生、教室）が別の意味を持ち始めるのです。もう複雑になってきました。

>複雑になり始めたこれらの情報を、どのように整理すれば、アプリケーションを作ることができるのか。

その答えは簡単なようで、とても効果的です。物流と金融の2つのドメインが見つかりました。それぞれのドメインが、**同じ概念に対してユニークな視点**を持っていることがすぐにわかると思います。

プログラムを管理する最良の方法は、**顧客ベース**、つまり**トップダウン方式**をとることです。この方法では、ソリューションをどのように作成するかに焦点を当てるのではなく、作成する必要があるソリューションの「**何**」と「**なぜ**」を理解しようとします。ドメインモデルは、この「何を」「なぜ」という重要な概念を、誰もが理解できる言葉で表現したものです。

>しかし、なぜそれが重要なのでしょうか？


見せてあげるよ。試しに、お客さま（私）と開発者（あなた）の役を演じてみましょう。では、「本」というシンプルなものにも同じ定義があるかどうか、見てみましょう。考えてみてください。本とは何ですか？さあ、紙を取るか、お気に入りのブラウザで新しいタブを開いてみてください。そして、定義を書く：本とは何か？

体にいいのか？

さて、では私の答えはというと、*図書館で借りられる物理的な物体です。*

>"図書館"？申し訳ありませんが、いつですか！？ 🤨 何の脈絡もないですね。どうやってあなたの定義がわかってられるのでしょう？

その通り！これで、顧客と協力せずに、顧客を満足させるコードを書くことがなぜ難しいか、おわかりいただけたでしょうか。顧客の**専門用語**や**文脈**を理解する必要があるのです。特に、異なる文脈で異なる人々と接する場合、単純な用語でさえも異なる意味を持つことがあります。重要なのは議論です。思い込みは禁物です。

## ドメインモデルがどのようなものか確認

ドメインモデルを表現する方法はたくさんあります。wikiのページで箇条書きにする形をとることもできます。最も一般的な方法の1つは、**ダイアグラム**を使用することです。

### ポップカルチャーで最初のドメインダイアグラムを作成

ここではまさに、プログラムから見た領域のモデル、つまり「どう作るか」というボトムアップのアプローチとは対照的な、トップダウンのロジックになっているのです。この段階では、データベースやオブジェクト、クラウドの導入など、技術的な成果にはこだわらない。

![usecase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657937/f507a629-733e-2928-765a-8a76be3a19ff.png)


*この図（と下のトピックの図）は、UMLとして知られているUnified Modeling Languageを使って作成されました。*

### ドメイン駆動設計を活用する

さて、ドメインモデルの価値がわかってきたでしょうか？最大のメリットは、**開発者がプログラムをビジネスの観点から理解**できるようになることです。ビジネスを理解するということは、企業がどのようにお金を稼ぎ、顧客を維持し、獲得しているかを理解するということです。企業は常に変化しています。顧客を維持し、新しい顧客を獲得するために、同じ顧客に喜んでもらえるような機能を考案していきます。

ドメイン駆動設計の2つ目の利点は、ドメインの視点からアプリケーションを作成すれば、変更を容易に実現できるということです。別の例を見てみましょう。

![class.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657937/261acbd5-bb6c-044a-6760-f514bbe4273b.png)

この図は、タクシー会社に関連する主要な要素を示しています。旅行という概念が、私たちのモデルの中心にあることがおわかりいただけると思います。お客さまから依頼される。カー・ドライバーはそれを提供します。さらに、各旅行に対して支払いが行われますが、この支払いは「場所」に依存します。

次に、ドメインテンプレートのPayment要素を見てみましょう。まだかなり一般的なものです。現金」や「クレジットカード」が指定されていないのです。もし、暗号通貨での支払いを許可したいのであれば、それは全く問題ありません。これにより、この方法で支払いを行いたい顧客が十分にいるかどうかをビジネスロジックが判断し、その顧客専用の機能を実装することができます。


## 何を学んだ
- 真っ先にコードに飛びつかず、まずはモデルを作ることから始める。
- ドメインモデルとは、システムの本質的な要素を捉えたものである。お客さまとのニーズのやり取りが容易になるため、複雑なソフトウェアをより理解しやすく設計することができるのです。
- ドメインモデルは、複数の区切られたドメインまたはコンテキストを持つことができる。
- ドメインモデルには、UMLダイアグラム、Wikiページ、コードなど、さまざまな形態があります。
- モデルを作るときは、「どのように」ではなく、「何を」「なぜ」という問いに重点を置くこと。

*ドメインモデルとは何かということが分かったところで、次の章では、モデルのアウトライン化に必要なステップを学びます。*