#5【勉強メモ】エヴァンス本からざっくり理解する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)を通して体系的に学習する
・各章の要約をアウトプットすることで知識を定着させる

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

https://qiita.com/kotemendo2819/items/4ec669c809ceccef0bf6

## 【第5章】ソフトウェアで表現されたモデル
### `関連`
オブジェクト間の関連を扱い安くるす方法は3つある。
1. 関連を狭う方向を強制する(一方通行)
2. 限定子を付与して、多重度を効果的に減らす(一対多を減らす)
3. 本質的でない関連を除去する(モデルに必須でない機能を減らす)

## `エンティティ`
・エンティティ
同一性によって定義されるオブジェクト。
ライフサイクルを通じた連続性を持ちユーザーにとって重要な区別が属性から独立しているもの。
例)人、都市、自動車、宝くじ、銀行取引

### `エンティティをモデル化する`
ふるまいが明確で予測可能になるよう、連続性を確立する。
例)顧客IDを定義し識別しとして使用する。

### `同一性のための操作を設定する`
アプリケーションが外部のID(電話番号など)を必要とした場合、
ユーザーが一意のIDを提供することになるためシステム側は発生する例外を十分に
処理しなければならない。

## `値オブジェクト`
・値オブジェクト
ドメインにおける記述的な側面を表現し、概念的な同一性がないオブジェクト。
例)文字列、数

### `値オブジェクトを設計する`
値オブジェクトは、オブジェクト間でコピーや共有が可能だが、
値が変更されてしまうことを防ぐためオブジェクトを不変にしなければならない。

### `値オブジェクトを含む関連を設計する`
値オブジェクトは同一性がないため、オブジェクト同志の双方向の関連は完全に取り除くようにする。

## `サービス`
・サービス
モデルにおいて独立したインタフェースとして提供される状態を持たない操作で、
エンティティや値オブジェクトとのようにカプセル化しない。
ドメインに関係しているがその概念がエンティティや値オブジェクトの一部だと不自然な操作。
例)ドメインにおける重要なプロセス、変換処理

### `サービスと隔離されたドメイン層`
サービスはドメイン層以外でも使用されるため、他の層に属するサービスと区別し
それぞれの責務を分解する必要がある。

### `粒度`
概念をサービスとしてモデル化することで、クライアントをエンティティや値オブジェクトから分離する手段や
ドメイン層のインターフェースの粒度を制御する手段としても価値がある。

### `サービスへのアクセス`
サービスへのアクセス制御は、責任分離ほど重要ではないので、
サービスのインターフェースの実行オブジェクトがあれば十分。

## `モジュール(パッケージ)`
モジュールは低結合、高凝集でユビキタス言語の一部になる名前をつけることが推奨されている。
モジュール全体によって圧倒されることなくモジュール内部の詳細を見ることができたり、
逆に詳細を無視した上でモジュール間の関係性を理解することができるというメリットがある。

### `アジャイルモジュール`
モジュールの選択において初期の間違いを引き継いで高結合になることでリファクタリン困難な状態が発生するが
それを克服するためには経験に基づきモジュールを再構成していくしかない。

### `インフラストラクチャ駆動パッケージングの落とし穴`
##### 1. コードがモデルを反映しなくなる
フレームワークの規約でオブジェクトが分散することでコードがモデルを明らかにすることがなくなる。
##### 2. モデルを認識できなくなる
頭の中で元通りにできる分割には限りがあるため、超えてしまったモデルは意味のある塊として認識できなくなる。

単一概念オブジェクトのコードは同一モジュールにまとめたり、
ドメインを他レイヤから分離するためにパッケージングしていくことが大切。

## `モデリングパラダイム`
モデル駆動設計を実践するためには、特定のモデリングパラダイムに合わせた
オブジェクト指向設計等の実装技術が必要だ。

### `なぜオブジェクトパラダイムが主流なのか？`
概念はシンプルだが、ドメインについて重要な知識をとらえらる表現の豊かさがある。
また開発者コミュニティと設計文化の成熟が挙げられる。

### `オブジェクトの世界におけるオブジェクトではないもの`
プロジェクトでは支配的なモデルパラダイムに関わらず、他のパラダイムを取り入れることで
容易にモデリングできるケースがある。
その際、開発者はパラダイムが首尾一貫したモデルでなくても明確に理解しなければならない。

### `パラダイムを混合させる際にはモデル駆動設計に忠実であること`
異なるパラダイムを混在させる際の経験則

##### 1. 実装パラダイムと対立しないこと
ドメインに関する別の考えかたは常にあるのでパラダイムに適したモデルの概念を見つけること。

##### 2. ユビキタス言語に頼る
言語を一貫させれば、ツール間の各設計部分が別れない。

##### 3. UMLにこだわらないこと
モデルに合わせた作図スタイルの選定や、自然言語での記述も考慮する。

##### 4. 懐疑的であること
ツールの動きや必要性について懐疑的であること。

## `まとめ`
モデルの要素や、効果的なパッケージングについて学ぶことができた。
次はドメインオブジェクトのライフサイクルについて学んでいく。

https://qiita.com/kotemendo2819/items/4120a11f7a1304688c6f

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