「実践ドメイン駆動設計」のまとめと感想
- Published on
この記事には、実践ドメイン駆動設計の各章のまとめと感想が書かれています。(2021 年 5 月現在執筆中です)
実践ドメイン駆動設計とは
- 書籍 :実践ドメイン駆動設計 (Object Oriented SELECTION)
- 著者:Vaughn Vernon
- 内容:ドメイン駆動設計の実践方法
- 原著発売年:2013 年
『エリック・エヴァンスのドメイン駆動設計』は、2003 年の刊行だったにもかかわら ず、大型ソフトウェア構築時につきまとう不透明感を払拭するための指針として現役技 術者に多大な影響を与えた。ある意味、エリック・エヴァンスの先見性によって、今日 、必要とされるパタン/アンチパタンが整理されていたためだ。とはいえ、それからす でに 11 年。ベースとなるオブジェクト指向はそれほど大きな変革はないものの、この 10 年の間にコンピューティングの対象は大きく増え、さらにドメイン駆動設計をコト バでは知っているものの、経験値のまだ低い技術者の増加もあり、理論だけではなく現 状に則した形で体得する必要性が増している。本書は DDD の考え方はもちろん、コミ ュニティや実際のビジネスシーンのなかから実践的な方法論を精錬し、いわば 21 世紀 (初頭)型ドメイン駆動設計を伝授するものであり、現在のニーズに合致する内容で構成 されている。(amazon 商品説明より)
著者の情報は、vaughnvernon.comに、まとまっています 。
Blog や Podcast にて、ドメイン駆動設計のみならずマイクロサービスアーキテクチャや リアクティブアーキテクチャについての発信活動もされているようです。
どのような人が読むと良さそうか
下記のどれかに当てはまる方がターゲットと思います。
- ドメイン駆動設計を実務で実践したい人
- ドメイン駆動設計の実装方針を掴みたい人
- アプリケーションコードの設計改善のヒントを得たい人
僕は、DDD の実装方針を掴んで、アプリケーションコードの設計改善が行えるようになり たいと思ったので読んでいます。本記事は 『「実践ドメイン駆動設計」から学ぶ DDD の実装入門』も 参考にしています。
各章のまとめ
第 1 章 DDD への誘い
追記予定
ロードマップ
重要と思った点
疑問と回答
第 2 章ドメイン、サブドメイン、境界づけられたコンテキスト
追記予定
ロードマップ
重要と思った点
疑問と回答
第 3 章コンテキストマップ
追記予定
ロードマップ
重要と思った点
疑問と回答
第 4 章アーキテクチャ
追記予定
ロードマップ
重要と思った点
疑問と回答
第 5 章エンティティ
この章は、エンティティを適切に重視する方法・エンティティの設計に関するさまざまな テクニックについて書かれている。
ロードマップ
- 一意なモノをモデリングする必要があるときに、なぜエンティティが適切な場所なのか を考える
- エンティティ用の一意な識別子を生成する方法を調べる
- 設計の現場に立ち寄り、チームがユビキタス言語をとらえたエンティティを設計するよ うすを見る
- エンティティの役割と責務を表現する方法を学ぶ
- エンティティの検証と永続化の実例を見る
エンティティには一意な識別子があって、変化するという特性がある。これが値オブジ ェクトとは異なる点だ。
重要と思った点
- 値としてモデリングすべき概念をエンティティとしないように注意しよう
- エンティティ設計の初期段階は、一意に特定するためのポイントとなる属性や振る舞い だけに注目しよう
- 一意な識別子の作成方針はメリデメを持った複数の選択肢があるので適切なのを選ぼう (書籍では 4 種類を紹介)
- 一意に識別可能である && 変更に対応する => エンティティ
- エンティティと値オブジェクトをどちらにするか判断する際の鍵は、「変更」という言 葉
- 委譲は、設計を簡単にする場合にのみ選択すべき技術
- 不変条件は集約の関心事ではあるが、集約のルートは常にエンティティなので、エンテ ィティが不変条件を保持することもある
- 単一の属性あるいはプロパティに、不適切な値が設定されないようにするためには、自 己カプセル化が推奨される
疑問と回答
- なぜ一意に特定することを最重視するのか?
- そもそも、システム内の他のオブジェクトとの区別が必須である時に、ドメイン の概念をエンティティとして設計する
- エンティティの目的であるオブジェクトを一意に特定することが最重視される
- そもそも、なぜオブジェクトを識別する必要があるのか?
- ?
- バリデーション・アサーションの文脈で登場した「契約による設計」とは何か?
- コードの利用条件を定めることによって、エラーの位置を明確にし、設計の安全性を 高める手法(?)
- D 言語のドキュメントが分かりやすい → 契約プログラミング
第 6 章値オブジェクト
ロードマップ
重要と思った点
- あるモデル要素の属性のみが関心の対象となるなら、値オブジェクトに分類される
- 「一意に識別して変更を管理する必要が無いモノ」を値オブジェクトとする
- 「計測/定量化/説明・不変・概念的な統一体・交換可能性・等価性・副作用のない振る 舞い」の全てを満たす
疑問と回答
第 7 章サービス
第 8 章ドメインイベント
第 9 章モジュール
第 10 章集約
この章は、集約を用いる意義とその実装テクニックについて書かれている。
ロードマップ
- SassOvation とともに、集約を不適切にモデリングしたときの悪影響を経験する
- 集約の経験則をベストプラクティスの指針として、設計について学ぶ。
- 実際のビジネスルールに沿って、整合性の教会内のシンの不変条件をモデリングする方 法をつかむ。
- 小さな集約を設計するメリットを考える
- 集約から別の集約を参照する際に、その識別子を使うよう設計すべき理由を学ぶ
- 集約の境界の外部で結果整合性を使うことの重要性を見つける
- 集約の実装テクニックとして、「命じろ、たずねるな」やデメテルの法則などを学ぶ
重要と思った点
- 集約とは、トランザクション整合性を保ちながら更新を行うオブジェクトのまとまりの こと
- オブジェクトの集まりの境界線という意味で使われる
- 外部からは集約ルートエンティティのみを参照できる
- 小さな集約を作るべき
- トランザクションの衝突可能性を小さくできる
- 他の集約ルートには、識別子のみを参照する
- 集約のコーディング時に役立つ法則
- デメテルの法則
- Tell-Don't-Ask の指針
- 集約での依存性の注入を避ける
- 参照先の集約の情報を永続化層から読み出す場合は、集約の外から事前に呼び出して おく方式が推奨されている
疑問と回答
- トランザクション整合性と結果整合性の違いとは?
- トランザクション整合性(= DDD の集約):同期的に整合性を保つ必要のある処理
- 結果整合性:
- 巨大な集約を作ることで起きる問題は?
- トランザクションの衝突可能性が著しく高くなる
第 11 章ファクトリ
ロードマップ
重要と思った点
- DDD におけるファクトリは「ユビキタス言語を用いて集約をシンプルに生成する」とい う意味合いが強い
- 一貫した(不変の)状態のオブジェクトのみを返すという制約がある
疑問と回答
第 12 章リポジトリ
リポジトリは、エンティティや値オブジェクトから構成される「集約」の格納と取得を担 当する。通常、集約とリポジトリは一対一になる。
ロードマップ
- 二種類のリポジトリがあることと、それぞれをどんなときに使うのか学ぶ
- Hibernate や TopLink、Coherence、そして MongoDB でのリポジトリの実装方法を見る
- リポジトリのインターフェイスに追加の振る舞いが必要になる理由を理解する
- リポジトリを使う際の、トランザクションの扱いかたを検討する
- 型の階層がある場合にリポジトリを設計する際の、注意事項を知る
- リポジトリとデータアクセスオブジェクト[Crupi et al.]の根本的な違いを見る
- リポジトリをテストする方法や、リポジトリを使ったテストを行うためのいくつかの方 法を検討する
重要と思った点
- リポジトリには「コレクション指向のリポジトリ」と「永続指向のリポジトリ」の二種 類がある
- 認証・アクセスコンテキストのような、一対一のマッピングを使った集約の削除の際に は、関連の両側にあるオブジェクトを、明示的に削除する必要がある。
- 関連するオブジェクトの削除が面倒になるので、一対一の関連は避けるべき。
- 永続化は、リポジトリだけに任せておきたい(集約に管理させたくない)
- 複数のリポジトリ上でユースケースに最適化したクエリを使うファインダーメソッドを 数多く作る必要が出てきたら、それは集約の境界の判断を誤り、さまざまな型の集約を 設計するチャンスを見落としていた兆候
- ドメインモデルの永続化に関するトランザクションは、アプリケーションレイヤを用い てとりまとめる
- ストアドプロシージャの濫用は、実装がモデリングチームに見過ごされる可能性がある ため、DDD の秩序を乱す可能性がある
疑問と回答
- コレクション指向のリポジトリとは?
- 更新系のメソッドを持たないクラス
- RDB やインメモリで格納する
- 永続指向のリポジトリとは?
- 更新系のメソッドを持つクラス
- 集約のキーをもとに、集約の階層構造を 1 つのデータとして NoSQL に保存する
- こちらでは、永続化処理を全てリポジトリに詰めることができるので高凝集となる
- リポジトリと DAO の違いは?
- リポジトリ:ドメインモデルと組み合わせて使われる
- DAO:データベースのテーブルに対するラッパーとして使われる
- トランザクションスクリプトとは?
- get と find の違いは?
- get:取得(そのメソッド内で特に何も処理をせずに値を取得、値がなければエラー )
- find: 検索(そのメソッド内で何らかの処理をして値を取得。値がなければ null)
学習のためのリンク
第 13 章境界づけられたコンテキストの統合
ロードマップ
重要と思った点
疑問と回答
第 14 章アプリケーション
ロードマップ
重要と思った点
疑問と回答
追記予定
全体の感想
思っていたより読みやすいと思う。