#9【勉強メモ】エヴァンス本からざっくり理解するDDD

## 目標
・ふわっとした理解のDDDについて[エヴァンス本](https://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=17W0M5YAY0R9Z&dib=eyJ2IjoiMSJ9.qtIEGNumTF4Fq3OG4r7BcgPPpMccQaiAMFjoQiYsRfAUl2LJ3kucBAwXJG1pE1-9MMyozf_R6XnUk8kwhpkIPyRMzsu94DrC82a2cWHXn2TDjembTcFwG0z4uuYeu7EY_VF_p_KcGaJhu-sFQP2IfF8BXdAN9RWcUsZLGOA8hIhkuAKrptA3cagpPrF5ZoxXjjZ9ctVxNzHN-qanc6enklCzFiHeCY1UpXho238Cgd4eMsXlRTbQ5u_T9ZSbUOj5EOjKzf1jx0xSJbTwFJrRetDuJaorGcsbbNpAuJkvNAs.F3zE4YfUXPLj7DRzsSV4wM07EgTKoLqmpU491uMjIhw&dib_tag=se&keywords=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88&qid=1710421495&sprefix=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88%2Caps%2C279&sr=8-1)を通して体系的に学習する
・各章の要約をアウトプットすることで知識を定着させる

## 前回の記事
第8章の内容は以下でまとめています。

https://qiita.com/kotemendo2819/items/77596ea89831f0074cae

## 【第９章】暗黙的な概念を明示的にする
ドメインモデルとコードが大きく変化するのは、議論や設計内の暗黙的な概念をモデルの中で明示的に表現した時だけである。

## 概念を掘り出す
暗黙的な概念を発見するためには、チームの言葉に耳を傾け、
設計の矛盾点を調べドメインに関する文献を読むといったことを行う必要がある。

### `言葉に耳を傾ける`
ドメインエキスパートの使う言葉に耳を傾ける
・複雑なものを簡潔に述べている用語がないか？
・言葉選びを正されていないか？
・特定のフレーズに対して、困惑した表情をしていないか？

### `ぎこちなさを精査する`
手続きによって説明しにくい複雑な処理や、新しい要求のたびに複雑になるような設計に対して
積極的にドメインエキスパートを調査に参加させモデルを蒸留させる。

### `矛盾について熟考する`
矛盾を解決することは現実的でない場合もあるが、
異なる２つの記述が両方とも適用できるかどうかを熟考することで明らかになることもある。

### `文献を読む`
基本的な概念や社会通念について解説している文献を読むことで
首尾一貫し深く検討されたモデルに対する見方をえられる。

### `何度も挑戦すること`
リファクタリングをするたびに、設計はよりしなやかになり、変更が容易になる。

## それほど明白でない概念をモデル化する方法
オブジェクト指向の概念で理解難しい３つのカテゴリをモデル化する。
・制約
・プロセス
・仕様

### `明示的な制約`
```java:制約の意義を明確かつ明示的に表現する
/**
*バケツクラス
*/
class Bucket {
  // 最大容量
  private float capacity;
  // 内容量
  private float contents;

  /**
  * 注ぐ
  * @param addedVolume 加えられた量
  * /
  public void pourIn(float addedVolume){
    float volumePresent = contents + addedVolume;
    contents = constrainedToCapacity(volumePresent);
  }

  /**
  * 最大容量以下に制限する
  * @param 入れられた量
  * @return 入れることのできた量
  * /
  private float constrainedToCapacity(float volumePlacedIn){
    if(volumePlacedIn > capacity) return capacity;
    return volumePlacedIn;
  }
}
```

制約によってオブジェクトが歪められる例
1. 制約を評価するために、オブジェクト定義に合わないデータが必要になる
2. 関連するルールが複数あるせいで、コードの重複や別の系統のオブジェクトを継承しなければならなくなる
3. 実装で制約が手続型のコードの中に隠されてしまう

### `ドメインオブジェクトとしてのプロセス`
サービスはドメインのプロセスを明示的に表現しつつ、極端に複雑なアルゴリズムを引き続きカプセル化する方法の1つだ。

## 仕様
・仕様
特殊な目的をもった述語的な値オブジェクトで、あるオブジェクトが何らかの基準を満たしているか判断するもの。
※述語・・・「真」or「偽」を評価する関数。「AND」や「OR」などの演算子を使用して結合することで表現される。

### `仕様の適用と実装`
オブジェクトの目的が以下のいずれかに当てはまる場合、仕様を定義する必要がある
・オブジェクトを検証し、要求を満たしているか、何らかの目的のための準備ができているか調べる
・コレクションからオブジェクトを選択する
・要求に適合するオブジェクトを新規作成する

・検証
仕様の最も単純な用途で、仕様という概念を最も直接的にしめす利用法。

### `要求に応じた構築(生成)`
仕様の代わりにジェネレーターのインターフェースを記述的な仕様の形で定義することで
ジェネレーターの生成物を明示的に制約できる。以下のようなメリットがある。

・ジェネレーターの実装がインターフェースから分離される。
・インターフェースが明示的にルールを示すので開発者は詳細を理解しなくてよくなる
・インターフェースが柔軟になる
・インターフェースのテストがしやすくなる

## まとめ
暗黙的な概念をモデル化する方法について学んだ。。
仕様に関して、本の中では検証だけのパターンや選択のパターンなどサンプルソースを交えて
解説されており理解を深めることができた。
次は「しなやかな設計」です。

https://qiita.com/kotemendo2819/items/d59acb2188bbb9570018

参考になったらいいねやコメントおまちしています！！