[Book]関数型ドメインモデリング 読書ログ
関数型ドメインモデリング ドメイン駆動設計とF#でソフトウェアの複雑さに立ち向かおう
日本語版が出たので読書開始。
DDDで開発進めてるが、
最近コード書く前に疑似コードでの整理をしだして
知る必要があったのがこの本購入のきっかけ。
ここにログとして残そうと思う。
🚩 1部: ドメインの理解
本番環境にリリースされるのはドメインエキスパートの理解ではなく開発者の理解だということ
"問題概要と解決手段の洗い出し"
📍1-1 モデル共有の重要性
要件収集 = 開発者とドメインエキスパートで共通理解を築くことが重要
ドメインエキスパート(業務の専門家)のメンタルモデルをコードに翻訳するが、
ドメインエキスパートと開発者の間に仲介が入ることでこの翻訳には歪みが生じる可能性がある.
ソフトウェアモデルとビジネスドメインを一致させることのメリット
- 市場投入までの時間短縮
- ビジネス価値の向上
- 無駄の削減
- メンテナンスと進化のしやすさ(モデルにドメインが集約されていてコード変更が容易)
📍1.2 ビジネスイベントによるドメインの理解
📝 ガイドライン①:"データ構造ではなくビジネスイベントやワークフローに焦点を当てる"について
<理由>ビジネスは単にデータを持っているだけではなく、何らかの方法でデータを変換するから
→ ビジネスは連続的な変換の流れとして捉え、
どのように機能し、互いに関係するかを理解することが大切
ここで言ってる"ビジネス"とは:
価値を生み出し、提供するプロセス全体のこと
補足: "ビジネス"とは
- ここで言ってる"ビジネス"とは:
上記した通り、価値を生み出し、提供するプロセス全体のことだが、
具体的には、企業の中で日々行われるさまざまな業務や取引、運営に関わる活動のことを指している。
EX.) ECサイトの場合:
「注文を受ける」→「在庫確認」→「発送準備」→「出荷完了」
- これらの活動が連携して、顧客のニーズを満たし、企業が利益を得る仕組みが"ビジネス" で、
ここでのポイントは、
単なるデータの保持ではなく、データを活用して何かを「実行する」一連のプロセスに焦点が
当てられていることだ。
▶️ ドメインイベントとは...ビジネスの流れを引き起こす重要な出来事
- この出来事をトリガーとして、次のプロセスが開始され、ビジネスの価値が生まれるもののこと。
-
ドメインイベントは常に過去形で、「○○した」「○○された」と書かれる。
きっかけとなったイベントは、変更できない事実だから だ。
▶️ ドメインイベント探索:"イベントストーミング"について
- 目的:ビジネスイベントと関連するワークフローを発見するための共同プロセス。
- 方法:ドメインの異なる部分を理解する様々な人々を集め、ワークショップ形式で実施。
- 参加者:開発者やドメインエキスパートだけでなく、成功に関わる他の関係者も含むべき。
- 進行方法:
壁に紙やホワイトボードを貼り、参加者が付箋を使ってビジネスイベントを書き出し、
議論や整理を進める。
→ 知っていることを書き、分からないことは質問するという形式(全員の積極的な参加促進)
終了後には、多くの付箋が壁に貼られた状態になることが理想的。
参考文献:この手法の詳細はAlberto Brandolini氏の『EventStorming』が推奨
自分も考えてみる"イベント告知関連のドメインイベント"のイベントストリーミング
自身が作成してるコミュニティアプリの"イベント告知関連のドメインイベント"で考える
<イベントリスト>
- イベント作成した
- 作成されたイベントがコミュニティ内で告知された
- イベントに参加登録した
- イベントの内容が編集された
- イベントの詳細が更新された
- 公開されたイベントが中止され、キャンセルされた
- イベント参加をキャンセルした
- イベントが開始された
- イベントが終了した
- レポート依頼した
- アフターレポートをもらった
💡コマンドの文書化💡
"そのイベントを引き起こしたのは何ですか?"
- この依頼を"コマンド"と呼ぶ。 (⚠️ OOPで出てくるコマンドパターンとは別物)
- コマンドは常に"〇〇する"で現在系でかかれるもの。
📍1-3. ドメインをサブドメインに分割する
📝 ガイドライン②: "ドメインをより小さなサブドメインに分割する"
- ドメイン内に特定の分野や知識が存在し、特定の領域(サブドメイン)として分けられることもある。
- サブドメイン: ドメインをさらに細かく分割した領域
- サブドメインは時に複数のドメインと重複し得る。
- ex. "CSS"で例えたら...
CSSは"webデザイン"ドメインの一部でもあり、"webプログラミングドメイン"の一部でもある。
→ 現実は明快な境界値はつけづらく曖昧
しかし!!!!!!
ソフトウェアの世界では、別々のサブシステム(コンテキスト)の結合を減らし、独立して進化できるようにしたい
- ex. "CSS"で例えたら...
📍1-4. 境界づけられたコンテキストを利用した解決手段の作成
▶️ 問題空間と解決空間
- 問題(ドメイン)の理解ができたら、その解決手段が必要だが、関連する情報のみを取り入れるようにしなければならない。
- ポイントは問題空間と解決空間の区別をして異なるものとして扱うこと
→ 問題空間のドメインのモデルを作り、そこから必要な情報を抽出して解決空間に再作成する
- ポイントは問題空間と解決空間の区別をして異なるものとして扱うこと
▶️ "境界づけられたコンテキスト"
- 解決空間では、ドメインやサブドメインが境界づけられたコンテキストとしてモデル化され、
特定のシステム内の役割を明確にする
▶️ 境界づけられたコンテキストの役割
-
DDD(ドメイン駆動設計)では、各コンテキストに明確な境界を設け、
異なるコンテキスト間での依存や相互作用を整理
→ ソフトウェア設計が 複雑にならないように する- 境界を意識することで、ドメインの重複や曖昧さを減らし、設計や開発が効率的になる
-
コンテキストを正しく反映することの重要性:
- ソフトウェア設計の整合性を保つ
→ これにより、機能の重複を防ぎ、各コンテキストの責務を明確にすることができる
複雑さを減らしてメンテナンスを容易にしたいのだ。
- ソフトウェア設計の整合性を保つ
▶️ その上で明確な責務を持たせることが重要
▶️ コンテキストを正しく区別する
→ ドメイン駆動設計の最も重要な課題の一つ。
ポイント
- ドメインエキスパートの声に耳を傾ける
- 既存チームや部門の境界に注目する
→企業がドメインとサブドメインをどのように考えているかの手がかりになる。 - "境界づけられた" を忘れない
- 摩擦の少ないビジネスワークフローを目指して設計する
→ 複数のコンテキストで相互に作用してワークフローが遅延する場合、
コンテキストのリファクタが必要。
"どのような設計も静的ではなく、ビジネス要件の変化に応じてモデルを進化させる必要がある"
→ もっと後章で解説
▶️ コンテキストマップ: コンテキスト間の相互作用を伝える方法
上記のように、コンテキストを定義したあとはコンテキスト間の相互作用を伝える方法が必要。
-
このコンテキストマップの役割は、
様々な境界づけられたコンテキストのその関係性を詳細までではなく、システムの全体を示すこと。 -
この中(ドメインを扱う中)ではコアドメインの存在も明確になってくる
→ ビジネス上の優位性もをちお金をもたらす部分のこと。- コアではないドメインのことを"支援ドメイン"
- 企業固有のものでなければ"汎用ドメイン"
-
実装ではこのように優先順位をつけて最も価値のあるコンテキストから拡大する
📍1-5. ユビキタス言語 -- コードとドメインエキスパートは同じモデルを共有 --
-
設計に存在するものは、
全てドメインエキスパートのメンタルモデルに存在するものと同じである必要がある。
→ 逆を言うと、ドメインエキスパートの表現していないモデルを設計の中に含めるべきではない。