ドメイン駆動設計 第15章 蒸留 要約

# ドメイン駆動設計 第15章 蒸留 要約

エリック・エヴァンスのドメイン駆動設計の15章の要約です
社内勉強会用に作成しました

(15章はドメインをドメイン層に集約した後の話 ドメイン層の整理)

そのソフトウェアを特徴づける、ドメインのなかでも特別に価値のある部分を **コアドメイン** と呼ぶ

**蒸留とは...混ざり合ったコンポーネントを分離するプロセス**
15章では、コアドメインを蒸留するアプローチを提示している  

- コアドメイン
    - ドメインビジョン声明文
    - 強調されたコア
    - 隔離されたコア
    - 抽象化されたコア
    - 宣言的スタイル
    - 汎用サブドメイン
    - 凝集されたメカニズム
    - 意図の明確なインタフェース

→ 15章はドメインをドメイン層に集約はしたけれど、複雑になってしまっているドメイン達を整理する方法を記載しています、ということかと

## コアドメイン(CORE DOMAIN)

**コアドメインとは...システム内で最大の価値を付加すべき場所**

### コアを選択する

**選択するコアドメインは視点によって決まる**

そのソフトウェア、そのビジネスによって異なる  

- (例)為替取引をサポートするアプリケーションでは、より手の混んだ金銭モデルを必要とするかもしれない
- そのアプリケーションにおいては、通貨や為替レートはコアドメインになる

### 誰がこの作業をやるのか？

**ビジネスを熟知しているドメインエキスパートに協力してもらう**

モデルフレームワークを購入するという選択肢もあるが、カスタマイズされたソフトウェアの持つ最大の価値は、コアドメインを完全にコントロールできることにあることに注意しよう

## 蒸留の拡大

次項以降の導入

## 汎用サブドメイン(GENERIC SUBDOMAINS）

汎用サブドメインの作り方

1. 高凝集のサブドメインを見つける
1. 汎用的なモデルを括り出して、別のモジュールに入れる
    - 既製品による解決策や、公表されたモデルの採用を検討する
1. 分離したものを、開発の優先順位をコアドメインより下げる

(例として挙げられているもの) 売掛け金や、経費元帳、その他財務に関するもの汎用的な会計モデルで処理できるものタイムゾーン

### 例 2つのタイムゾーンの物語

以下の2つの開発で、タイムゾーンを独自で実装しようとしたがうまくいかなかった  
コアドメインから分離することだけは、行われていた

- 貨物輸送のスケジュールを立てるソフトウェアの開発
- 保険会社にて支払請求処理を行なうソフトウェアの開発

### 汎用とは再利用という意味ではない

できる限り多くの努力はコアドメインに対して行ない、サブドメインにには必要な場合のみ最低限に

### プロジェクトのリスク管理

技術的なリスクが大きいプロジェクトもあれば、ドメインモデリングのリスクが大きいプロジェクトもある

## ドメインビジョン声明文(DOMAIN VISION STATEMENT)

(蒸留のための補足的なドキュメント。情報を伝えて道案内をするという役割)

**約1ページで、コアドメインとそれがもたらす価値に関する簡潔な記述を作成する**

(モデルとコード自体の蒸留を続けさせる、技術系ではないチームメンバや経営陣、さらには顧客とも共有できる(独占すべき情報を除く))

## 強調されたコア(HIGHLIGHTED CORE)

(蒸留のための補足的なドキュメント。情報を伝えて道案内をするという役割)

**具体化する実装と合わせて印を付ける、ということをやる。具体的には以下の2つ**

### 蒸留オブジェクト

**コアドメインとコアを構成する要素間の主要な相互作用が記載された、簡潔なドキュメント(3〜7ページ程度)を作成する**

(形式は、クラス図やシーケンス図、テキスト、その他の図等よしなに)

### コアにフラグを立てる

(例)ドメインモデルの200ページの資料を通読し、コアドメインに印を付けて、読む人がコアドメインがどれなのかわかりやすくした

### プロセスツールとしての蒸留ドキュメント

モデルやコードを変更した際、*蒸留ドキュメント* に影響を与える場合は関係するチームと協議し、変更した蒸留ドキュメントを配布する

## 凝集されたメカニズム(COHESIVE MECHANISMS）

オブジェクト指向で、「どのように(how)」を隠蔽して、手続きを作っていっても、それが肥大化していくことがある  
howを提供するメソッドが大量に存在して、問題を表現するメソッド(本来、定義するべきメソッド)がわかりにくくなる

肥大化した「how」を提供するメソッド達を切り分け、別個の軽量のフレームワークにすること → **凝集されたメカニズム**

### 例 組織図におけるメカニズム

組織図に関するかなり精巧なモデルを必要とするプロジェクト

1. ↑「かなり精巧なモデル」は、形式主義である「グラフ」によって解決できる
2. そのグラフを辿るのに必要なルールとアルゴリズムを **凝集されたメカニズム** で実装した

モデルが複雑化することを避けることができた

### 汎用サブドメイン対凝集されたメカニズム

引き受ける責務の性質が異なる

- 凝集されたメカニズムは、あくまで処理のみを行なう

### メカニズムがコアドメインの一部である場合

メカニズムそのものが独占的で、ソフトウェアの価値を構成するものだったら...
→ より深い分析をすれば、モデルが生み出されるかもしれないが費用対効果による

### 例 一巡：組織図がメカニズムを再び吸収する

組織をモデルを完成させた一年後、グラフフレームワークをフレームワークとして分離するのをやめた  
ドメインモデルも増加して、これだけを独立させたパッケージに分離しておくのが微妙だったから

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

コアドメインが、蒸留されて、深いモデルになっていくと、
クライアントのコードも宣言的なスタイルになる

## 隔離されたコア(SEGREGATED CORE)

モデルをリファクタリングして、コアの概念の補助的な役割を果たすものを分離する
そうすることで、コアドメインの凝集度を高め、他のコードとの結合度を下げる
↑ 汎用サブドメインを適当する際と原則が同じだが、ここでは **コアから隔離する** ということを強調している
隔離したものをどの場所に置くかは、重要視していない

### 隔離されコアを作成するコスト

- コアと密接に結合した、コアではないクラス群との関係がさらに曖昧で複雑になる ※コアドメインを明確にして作業しやすくメリットのほうが勝る
- コアを隔離すること作業が大変
    - システム全体に影響する変更への対応に開発者を取られてしまう

### チームの意思決定を進化させる

**隔離されたコア** の作業をする際は、チームが一丸となって臨むこと
コアの隔離をする際は、何が本質的で何が補助的な要素かについて新しい洞察に繋がる
そういう洞察はチーム全体にフィードバックして、コアドメイン、隔離されたコアの改良に役立てる

### 例 貨物輸送モデルのコアを隔離する

**隔離されたコア** の作業の例
ドメイン声明文を読んで、補助的な役割を探していく...

## 抽象化されたコア(ABSTRACT CORE)

把握できるくらい小さなサブドメインに分割して、それぞれ別々のモジュールに入れる、というやり方は、複雑なモデルを扱いやすくするのに役立つが、サブドメイン間の相互作用があいまいになったり、かえって複雑になったりすることもある

抽象クラスかインタフェースに括り出し、重要なコンポーネント間の相互作用を表現するように設計する

**抽象化されたコア** は **蒸留ドキュメント** と非常に似たものになるはず

## 深いモデルの蒸留

(前述)蒸留とは、混ざり合ったコンポーネントを分離するプロセス

↑ ドメインを改良することも意味している
継続的なリファクタリングによって行われる

## リファクタリングの対象を選ぶ

リファクタリングをする際、どこから手をつけるのか

1. コアドメイン、またはコアと補助的要素の関係を含むもの
1. コアドメインのより適切な括り出し、コアの隔離、汎用サブドメイン化