# ドメイン駆動設計(DDD)の紹介 この章では、DDDの原理を議論し、どの様に特定のドメインに適応するかを示す。 ## 目次 - 共有モデルの重要性 - ビジネスイベントを通じたドメインの理解 - サブドメイン化 - コンテキスト境界を用いた解の創出 - ユビキタス言語の創出 - DDDの概念をまとめる - まとめ ## 共有モデルの重要性 問題解決(業務システム構築)には、問題や業務を正確に理解することが大切。 しかし、残念なことに、問題・業務を深く理解している人と、開発者は違うし距離がある。 **登場人物** - 開発チーム - 開発者 - UI/UXデザイナー - テスター - など - ドメイン専門家 ### 開発の流れ **よくある現実世界では** ![](https://i.imgur.com/QeVMJhp.png) いわゆるウォーターフォールモデルの開発。 伝言ゲームだとミスマッチが起こりやすい。 **より良い解決策** ドメイン専門家と開発チーム間でフィードバックループを作る。 "アジャイルな"開発手法。 ![](https://i.imgur.com/KN9nBzX.png) この方法にも(やり方によって)問題がある。 この方法では、開発者は翻訳者。話を聞いて、ドメイン専門家の心の内をコードに落とす必要がある。 開発者は容易に(翻訳の)ミスを起こしやすいし、ドメイン専門家も開発者に伝えにくい。 **最高の方法** 誰だろうが、同じドメインモデルを共有している。 これがドメイン駆動設計のゴール。 ![](https://i.imgur.com/vTmzmL5.png) ***ソフトウェアモデルをビジネスドメインに合わせることのメリット*** - 市場投入までの時間短縮 - より多くのビジネス価値の提供 - 無駄を省く - メンテや進化がしやすい **DDDのガイドライン** - データ構造ではなく、ビジネスイベントやワークフローに焦点を当てる - 問題領域(ドメイン)をより小さなサブドメインに分割する - ソリューション内の各サブドメインのモデルを作成する - プロジェクトに関わるすべての人が共有し、コード内のあらゆる場所で使用される共通言語(「ユビキタス言語」として知られている)を開発する ## ビジネスイベントを通じたドメインの理解 まずは、ビジネスイベントやワークフローに焦点を当てる。なぜか? ビジネスの価値は、変化のプロセスの中にあるため。 静的なデータは意味を持たない。 何によって、社員等は価値を創り始めるか? それは、**トリガー**(例えば、「メールが届く」とか「毎日10時」など)である。 これらを***ドメインイベント***と呼ぶ。 ドメインイベントは、常に過去形で記述される。 ### イベントストーミングを利用してドメインを発見する ドメインを発見するのに向いている方法は、***イベントストーミング*** ビジネスイベントと関連するワークフローを発見するプロセス。 このプロセスは、開発者やドメイン専門家**だけでなく**、様々なステークホルダーと一緒に(ホワイトボードに付箋を貼り付けながら)行う。 合言葉は、 > ***疑問を持っている人誰でも。答えを持っている人誰でも。*** ### ドメインの発見:受注システム 本書では、受注システムを例に設計、ドメインモデリング、実装を行う。 **イベントストーミング例** - 注文フォームを受け取った - 発注した - 発送した - 注文変更依頼がきた - 注文キャンセル依頼がきた - 見積書を受け取った - などなど ![](https://i.imgur.com/zK7YvHA.png) このプロセスで重要なこと - ビジネスの共有モデル - 全てのチームに気付く - 要件の中にギャップを見つける - チーム間のつながり - 報告義務の意識 ![](https://i.imgur.com/Vs33jNv.png) ### イベントをエッジにしていく イベントのトリガーや、イベントの終わった後に何をするかをさらに深堀りしていく。 :::spoiler ワークフロー、シナリオ、そしてユースケース シナリオ・・・顧客が達成したいゴールを記述する。 ユースケース・・・シナリオ詳細バージョン。 ビジネスプロセス・・・ビジネスが達成したいゴール。 ワークフロー・・・ビジネスプロセス詳細バージョン。(従業員やソフトウェアコンポーネントが達成すべき) ::: ![](https://i.imgur.com/ea1EpTa.png) ### コマンドを文書化する イベントが出そろったら、「ドメインイベントは何を引き起こすか?」を考える。 例えば、「顧客に注文フォームを受け取って欲しい」とか「上司に何かしてほしい」のような。 これらをDDDでは、「***コマンド***」と呼ぶ。 コマンド・・・***これを私のためにして*** コマンドが達成したら、再び、ドメインイベントが発生する。 ![](https://i.imgur.com/xgQewrf.png) 具体例 ![](https://i.imgur.com/7tjf8Vi.png) 全てのイベントがコマンドと関連づいている必要はない。 例えば、「月末になったら」や「ストックがいっぱいになったら」等のコマンドから発生するイベントも存在する。 ## サブドメイン化 いくつかのイベントやコマンドをリストアップできたが、全体像はいまだにカオスだ。 そこで、"ドメインをさらに小さなサブドメインに分ける" 試しに"order-taking process"を分ける - order taking - shipping - billing - ... エンジニアならこんな感じ ![](https://i.imgur.com/olya6Ba.png) 完全に分けられるわけではない。 ![](https://i.imgur.com/JZL7vWp.png) ## コンテキスト境界を用いた解の創出 ***問題領域***と***解決領域***に分ける オリジナルのドメイン(問題領域)だと、問題を解決するための全てが表現されている訳ではない。 そのため、解決領域を切り出す。 ![](https://i.imgur.com/qH5yiIp.png) この解決領域の一つひとつの領域のことを、**bounded context**と呼ぶ この、**bounded context**を創出することが、DDDにおける最も難しいことのひとつ。 これは、科学ではなくて技術。 ### 正しくコンテキストをつかむ ガイドライン - ドメインの専門家に聞く - 既存のチームや部門に注意を払う - bounded contextの**bounded**(境界)を忘れない - 自律設計 - 摩擦のないビジネスワークフローを実現するためのデザイン ### コンテキストマップを作成する コンテキストを定義したら、コンテキスト間のやりとりを記述する。 コンテキストマップを呼ぶ。 <!-- ![](https://i.imgur.com/2vYCVI6.png) --> ![](https://i.imgur.com/txFFmdL.png) ### 最も重要なBounded Contextsにフォーカスする 一般的に、あるドメインは、他のドメインよりも重要である。 (ビジネス優位性があり、お金を生む) ## ユビキタス言語の創出 [ユビキタス言語についての知見を共有します \- Qiita](https://qiita.com/kmdsbng/items/bf415afbeec239a7fd63) ## DDDの概念をまとめる - ドメインとは、私たちが解決しようとしている問題に関連した知識の領域、または単に「ドメインの専門家」が専門としている領域のことです。 - ドメインモデルとは、特定の問題に関連するドメインの側面を表現する一連の単純化のことです。ドメインモデルは解決空間の一部であり、それが表すドメインは問題空間の一部である。 - ユビキタス言語は、概念と語彙のセットです。チームメンバーとソースコードの両方で共有されているドメインを使用しています。 - 境界付きコンテキストとは、他のサブシステムと区別する明確な境界を持つソリューション空間のサブシステムのことです。境界付きコンテキストは,しばしば問題空間のサブドメインに対応します。また、バウンデッドコンテキストは、独自の概念や語彙を持ち,ユビキタス言語の独自の方言を持っています。 - コンテキスト・マップは、境界のあるコンテキストの集合とその間の関係を示す高レベルのダイアグラムです。 - ドメインイベントとは、システム内で起こった何かの記録です。常に過去形で記述されます。イベントは多くの場合、追加のアクティビティを誘発します。 - コマンドとは、人や他のイベントをトリガーにして、何らかのプロセスを実行するように要求することです。プロセスが成功すると、システムの状態が変化し、1つ以上のドメインイベントが記録されます。 ## まとめ ###### tags: `関数型` `DDD` `Fuctional`