はじめに
エンジニア3年目くらいに必ず勧められると言ってもいい本である『エリック・エヴァンスのドメイン駆動設計』、僕も読んだことはありましたが、正直よくわかりませんでした。
あれからしばらく経って、テックリードやマネージャーも経験し、今なら理解できると思ったので改めて読んでいきます。
日本語版への序文・日本語版推薦文・序文
この辺は読まなくていいと思います
前書き
ここもざっと読めば大丈夫です。
この本の内容を開発に取り入れる場合、前提として以下の2点必要であると書かれています。
- 開発がイテレーティブである
- 開発者とドメインエキスパートが密接に関わっている
「開発がイテレーティブである」とは、スクラムのようなアジャイル開発を採用しているということです。ちょっと作ってフィードバック→フィードバックを元にまた作ったり修正したり、というように少しづつ作っていくイメージです。ウォーターフォールのように、仕様が全て決まっていて作るだけ、という場合にはこの本は対象外になります。
ドメインエキスパートとは、作ろうとしているアプリケーションの専門家です。医療関係のアプリであれば医者だったり、経理関係のアプリであれば税理士かもしれないし、企業の管理部門かもしれない。開発しようとしているアプリが解決しようとしている「課題」があると思いますが、その「課題」に直面している人や、その課題の専門家のことです。
ドメインは日本だと「領域」で、特定の領域に詳しい人のことをドメインエキスパートと呼びます。
ドメイン駆動設計は、ドメインエキスパートと議論しながらアプリを構築していくことになるため、ドメインエキスパートの存在は必須になります。
謝辞・翻訳者謝辞
ここも飛ばして OK です。
第1部 ドメインモデルを機能させる
我々が何かアプリを作ろうとした場合、そのアプリは何かの課題を解決することになります。その際に開発チームはその課題に関する専門領域(= ドメイン)の知識を体系的に身につけなければなりません。会計ソフトであれば会計について詳しくなければ作れません。
そこで、ドメインエキスパートと議論をしながら、そのドメインの知識を「モデル」に落とし込んでいきます。「モデル」というのが概念的なものなのでわかりづらいですが、シーケンス図だったり、ドキュメントだったり、そのドメイン知識に対してみんなが共通の認識を構築できるようにするための何かです。
単にドメイン知識をモデルに落とし込むだけでなく、簡素化したものをモデル化する必要があります。作ろうとしているアプリケーションは何かの課題を解決しますが、その課題に関係ないものは無視して、必要な部分だけモデル化する必要があります。これが簡素化です。
ドメインエキスパートの頭の中にあるものから、アプリケーションに関係ある知識だけをまとめたものがモデルです。
そして、モデルが作成されたら、それを忠実にコードに落とし込みます。
ドメイン起動設計における、モデルの基本的用法(モデルをどう使うか)
- 作成されたモデルを忠実に実装に落とし込む(モデルと実装がが密接に結びつく)ことで、モデルに対する分析がそのままプログラムに反映可能になるし、モデルの理解に基づいてコードを解釈できるので、保守や継続的開発ができるようになる。
- 「うまく動作していなかったのは、モデルのここが不十分だったからだね。なのでモデルを修正し、改めてモデルをコードベースに反映させよう」となる
- モデルは、チームメンバ全員が使用する言語の基礎となる
- 開発のチームメンバーが共通の認識を持つこと(言葉の意味にブレがないこと)が重要であり、モデルを作成することで、チームメンバー間で認識を共有できる
- モデルとは、蒸留された知識である。最も関心のある要素を抽出している。
- 蒸留 = 必要なものだけ取り出して、それ以外の部分は排除すること
第1部第1章 知識を噛み砕く
最初にドメインエキスパートと開発者の会話の例があり、非常に長くてわかりづらいが、ここは読み飛ばしてよい。議論の内容を理解していなくても、なんとなく読むだけで問題ない。
モデルを作る → モデルを実装に落とし込む → 不具合あがればモデルを修正する、のサイクルを回していくことで、モデルが洗練されていく。モデルが洗練されていくということは、開発メンバーの知識が洗練されていくことでもあり、これを「知識の噛み砕き」と呼んでいる。
ドメインエキスパートと開発者が議論をしながら、問題解決のためのモデルを作成しているが、このモデルリングが効果的なものになるためのポイントがいくつかある
- モデルと実装を結びつける
- まず荒削りなモデルを作って、それを元に超簡素なプロトタイプを実装する。これによりドメインエキスパートもイメージがつきやすくなり、改善のサイクルが回っていくことになる
- モデルに基づいて言語を洗練させる
- モデルを洗練させていく過程で、専門用語も整理されていく。これにより開発メンバー間の誤解(言葉の齟齬)がなくなっていく
- 知識豊富なモデルを開発する
- オブジェクトには「ふるまい」と「守るべきルール」が実装されており、単なるデータスキーマではない
- 単にデータスキーマとしてもモデルを作成するのではなく、「ふるまい」や「ルール」などさまざまな知識を持ったモデル(= 知識豊富なモデル)を開発するように心がける
- モデルを蒸留する
- 新たな概念を追加していくだけでなく、役に立たないものを取りのぞいていくこと(=蒸留)も必要
- ブレインストーミングと実験を行う
- 実験のため、モデルにいくつかのバリエーションを持たせて、試してみるなど
知識の噛み砕き
これはすでに↑で説明した
継続的学習
一度モデルを作っただけでは終わらない。チームメンバーは入れ替わったりするため、継続的にその領域については勉強していかなければならない。
知識豊富な設計
- モデルによって表現されている知識は、単に名詞を見つける(用語を理解する)というだけではない。もっとさまざまな知識がある
- モデルは単にデータスキーマではなくて、ふるまいや守るべきルールが実装されている
- 例1.1 貨物のオーバーブッキングの例がある
- 船での貨物運搬の予約システムを作るときの話
- 急なキャンセルはよく起こることなので、許容量の110%の予約を受け付けるのが一般的である 単に if (capacty * 1.1 < 合計) のようなコードを書いても良いが、この 1.1 と言う数字がコードを読んでも、何に基づいた数字なのかが結びつかない
- OverBookingPolicy のようなクラスを作り、 OverBookingPolicy.isAllowed(capacity, 合計) のようにすることで、OverBookingPolicy と言う名前のルールがあることが明確になる
- これは、常にこうした方がいいと言うわけではい。OverBookingPolicy がドメインにおいて重要であれば、モデル化した方がいいと言う話
深いモデル
- 役に立つモデルがすぐにできるわけではない
- 試行錯誤してようやく完成したモデルが「深いモデル」