Please enable JavaScript.
Coggle requires JavaScript to display documents.
集約 (集約とは, モデルのコンテキスト, 異なる集約感の整合性, 複数の集約が関係する場合, リポジトリでドメインモデルを生成する方法) -…
集約
集約とは
集約単位で取得して、集約単位で更新する
repositoryを使う。repositoryが扱う範囲は集約単位
集約単位でトランザクションを貼る
集約ルートとは
特定の集約の親となるオブジェクト(エンティティかな?)
整合性を必ず守りたい対象の範囲
集約は広すぎると、トランザクション範囲が広がりロックしまくるので注意
モデルのコンテキスト
同じ言葉でも使う相手、場所によってモデルは異なる
商品の例
販売部からしたら、商品名とか在庫とか
配送部からしたら商品名とか配送先、配送状況とか
おそらくこのコンテキストごとに商品モデルを名前を変えて作るのだろう
異なる集約感の整合性
アプリケーションレイヤで他リポジトリを呼ぶ
コレは整合性がとれないこともある
書き方によっては
ドメインイベントを発火させて、他ドメインでサブスクライブする
複数の集約が関係する場合
異なる集約の場合
ID参照を使う
IDをMemberIdクラスとかにしたら、memberId以外は入り得ないので、正しさを担保できそう
同一集約の別オブジェクト(エンティティ)の場合
インスタンス参照
Memberの子のオブジェクトの特定のプロパティについて、Memberモデルでチェックをかけたいときに有効。IDだけだとできない
インスタンス参照で持たなくても良い場合もある
本当にその値が存在するかわからない場合
idをoptionalにくるむ
usecaseで例外を投げるのがいいかも
リポジトリでドメインモデルを生成する方法
すべてのプロパティを引数に取る、なんのバリデーションもしないコンストラクタを作成する
usecase層からそのコンストラクタ呼べてしまう問題
未バリデーションのドメインモデルのオブジェクトが生成できてしまう
その結果不整合なデータを作成できてしまう可能性がある
解決策
コンストラクタの名前を工夫する方法
ドメインモデルにfromRepositoryとかっていうstaticファクトリメソッドを作成して、その中でnewする
コンストラクタはprivateにしておいて、fromRepositoryからしか呼べないようにする
パッケージプライベートがない言語だと意図しないnewを防げないので、命名で回避しやすくする
javaのパッケージプライベートを使う方法
リポジトリのインターフェースと実装をdomain層におく
生成したいドメインモデルと同一のパッケージにおく
パッケージプライベートにすることで、usecase層からnewすることが不可になるので、意図しないオブジェクトの生成を防げる
ドメインモデルのコンストラクタをパッケージプライベートにする
あれでもこれrepository層がdomain層に入ることになるけど良いのかな?
gradleで依存関係定義している場合はusecaseからrepository呼べなくなるが、どうするんだろう...。
リポジトリの実装がドメイン層にあると、
インフラ層に依存してるような形になる気がする。だめでしょ?
やっぱりdomain層にrepositoryのabstractクラスをおいて、
インフラ層に実装クラスを配置すれば実現できそう
abstractクラスないの中小メソッド内でドメインオブジェクトの生成を行う
うーんこれはやりすぎ間あるな