エリック・エヴァンスのドメイン駆動設計  第15章 蒸留（後半部分）

## 社内勉強会用の資料です。

---
## 15章前半　振り返り
* ドメイン層にドメインを集めた後のタイミング
* コアドメインを見つけるために蒸留を進める
* コアドメインとはドメインの中でも特別に価値のある部分
* 前半で紹介された、蒸留のテクニック
    * 汎用サブドメイン
    * ドメインビジョン声明文

---

## 後半で紹介されている蒸留テクニック
1. 強調されたコア

1. 凝縮されたメカニズム

1. 蒸留して宣言的スタイルにする

1. 隔離されたコア

1. 抽象化されたコア

1. 深いモデルの蒸留

---
## 強調されたコア　１／5
* ドメインビジョン声明文には具体的な情報が不足している。
* 図やドキュメントが数点あれば精神的な拠り所やエントリポイントになる
* 補足する何かを作って開発に関わる全員がわかりやすくするテクニックが２つある

---
## 強調されたコア 2／5
##### 蒸留ドキュメント
* 簡潔なドキュメント（３~7ページ程度）を書き、コアドメインとコアを構成する要素間の主要な相互作用を記述する
* メンテナンスをラクにするために**最小限で中心的な抽象とその相互作用に集中する**

---
## 強調されたコア 3／5
##### コアにフラグを立てる
* モデルの主要なリポジトリ内においてコアドメインの各要素にフラグを立てる。
* コアかどうかを分かるように、本では膨大な資料のコア部分に付箋や蛍光ペンで線引きしていた。

---
## 強調されたコア 4／5
##### プロセスツールとしての蒸留ドキュメント
* 蒸留ドキュメントを指針として使う。
* モデルやコードの変更が蒸留ドキュメントに影響が与える場合には、他のチームメンバとの協議が必要である。変更したらチームメンバ全員に速やかに通知しよう。
* 蒸留ドキュメントに含まれていない詳細に対する変更は、協議なしで統合できる。

---
## 強調されたコア 5／5
##### まとめ
* ドメインビジョン声明文と強調されたコアは、ドキュメント。モデルやコードそのものを実際に変更することはない。
* これから挙げるパターンでは、モデルと設計自体を構造的に変更して、コアドメインをより見えやすくする方法を見ていきます。


---
## 凝縮されたメカニズム 1／4
##### 課題
* オブジェクト指向設計で、whatとhowを分離しても、限界に行き着くことがある。whatがhowに侵食されてしまう
* 問題を解決するためのメソッドが大量にあると、問題を表現するメソッドがわかりにくくなる。

---
## 凝縮されたメカニズム 2／4
##### 解決案
* 大量のメソッドを抽象化、概念的に凝縮されたメカニズムを切り分けで別個の軽量なフレームワークにすること
* 標準のアルゴリズムを利用する。意図の明白なインタフェースを用いて他モジュールから使えるようにすること
* 分離されたメカニズムは補助的な役割に置かれ、後に残される小さく表現力豊かなコアドメインは、以前よりも宣言的なスタイルになったインタフェース経由でそのメカニズムを使用する

----
## 凝縮されたメカニズム 3／4
##### 汎用サブドメイン 対 凝縮されたメカニズム
* 汎用サブドメインが基づいているのはモデルで、凝縮されたメカニズムはモデルから提起される、面倒な処理の問題を解決する。

----
## 凝縮されたメカニズム 4／4
##### メカニズムがコアドメインの一部である場合
* 証券会社の投資ロジックなど処理自体がコアドメインの場合は、費用対効果の分析に基づいてモデル化するかを考える

---
## 隔離されたコア １／6
* **汎用サブドメイン**で雑音を減らし、**凝縮されたメカニズム**によって複雑な処理がカプセル化される。
* 後に残るのはより焦点が絞られたモデルであるが、コアでないものも残っている。
* 「隔離されたコア」は、コアドメインを構造的に区切る

---
## 隔離されたコア 2／6
##### 課題
* コアに補助的な役割が絡んでいると最も重要な関係性を理解することが難しくなり貧弱な設計が作られることになる
* コアから補助的なものを分離する

---
## 隔離されたコア 3／6
##### 解決案：隔離されたコアを作る必要なステップ
1. コアではないものを識別

1. 関連クラスを、それを関連づけている概念に由来する新しいモジュールへ移動する

1. コードをリファクタリングして、その概念を直接表現していないデータと機能を切り離す。

1. 新しい隔離されたコアのモジュールをリファクタリング

1. 隔離されたこが完成するまで、別のコアサブドメインに対して前述のステップを繰り返す

---
## 隔離されたコア 4／6
##### 隔離されたコアを作るコスト
* 分離するための作業は大変。ただ、エンタープライズソフトウェアの価値は、モデルにあるエンタープライズに特化した側面から得られるので利点は大きい。


---
## 隔離されたコア 5／6
##### チームの意思決定を効率的に進める
* コアのリファクタリングを進めるためにチーム内のコミニケーションを効果的にする必要がある。

---
## 隔離されたコア 6／6
##### 例 貨物輸送モデルのコアを隔離する
* 初めは輸送モジュールと請求モジュールの２つ
* リファクタリングして、顧客合意クラスと顧客クラスをそれぞれ、配送モジュール（コアドメイン）、輸送モジュール（サブドメイン）に分割している。
* コアドメインがシンプルになり、サブドメイン、汎用サブドメインに整理されて扱いやすくなっていた。

---
## 抽象化されたコア  １／2
##### 課題
* 巨大なモデルを扱う時には、小さい限定的なサブドメインに分割して管理する
* しかし、別々のモジュールを作成することで、サブドメイン間の相互作用が曖昧になったり、複雑になったりすることがある。（追記：相互作用は依存やコミニケーションという単語に変換して読んでもよさそうです）
* 別々のモジュールに置かれたサブドミン間での大量の相互作用は、分割したことの価値をほとんど無くしてしまう


---
## 抽象化されたコア  2／2
##### 解決案
* 多態性を利用してバリエーションを吸収する
* モジュール間の相互作用のほとんどが、多態的なインタフェースで表現できれば、特別なコアモジュールに入れることは意味のあることかもしれない。
* 抽象（インタフェース）を分離することでモジュールが疎結合となり、小さく凝縮度の高いコアドメインが作られる。
* 抽象化されたコアは、最終的に蒸留ドキュメントに非常に似たものになる

---
## 深いモデルの蒸留
* 蒸留はコアからドメインの一部を切り離すだけではなく、コアドメインの改良も意味している。
* 目標はドメインをシンプルに表現すること
* プロジェクト全体の軌道を変えられるのは、コアドメインでブレイクスルーが発生した時だけ

---
## リファクタリングの対象を選ぶ
* 問題が起きている箇所がコアドメイン、コアと補助的要素との関係を含むものだったら、リファクタリングをする
* 自由にリファクタリングできる場合は、コアドメインの適切な切り出し、コアの隔離の改善、補助的なサブドメインから不純物を取り除くことによる汎用サブドメイン化を進める