強いて言えば「集約どう実装するのかなを考える」会 に参加しました。オンライン開催。簡単に所感をまとめます。
所感
ドメインモデルのトリレンマは初めて知りました。基本的には性能を保ちつつ完全性と純粋性のバランスを取るのがいいんだろうか。なんとなく repository をモックにするくらいならメリットに比べてテスト容易性が犠牲になってるとは思わないので、その程度なら許容してもいいかも。
「Parse, don't validate」や「Always-Valid Domain Model」のような設計はよさそうだけど、いわゆる「異なる概念」というのをいかに見つけ出すかが重要そう。当たり前だけど。
あと、最後の made functional の例を Java で書くとどうなるんだろう🤔 (あとで考える)
あとで読む。
- GitHub - kawasima/revisiting-domain-model
- ドメインモデル貧血症 - kawasima
- ドメインモデルの完全性と純粋性 - kawasima
- Always-Valid Domain Model - kawasima
以下、メモから抜粋。
- カートの情報をDBから復元してメモリにすべてロードする
- カートに追加
- 不変条件を満たすかチェック
- 不変条件はドメインモデルに実装したい
- スタジアム
- ランクごとの座席数上限
- OutOfMemory
- ドメインモデルのトリレンマ
- 完全性
- ドメインモデルにロジックを押し込める
- 高凝集/変更容易性
- 純粋性
- 他のレイヤに依存しない
- テスト容易性/移植性
- 性能
- すべてメモリにロードする設計だと上限次第では性能が犠牲になる
- 完全性
- 完全性+性能
- すべてメモリにロードしないが参照系では必要になる
- 更新と参照で扱いたいモデルが違う
- Read, Write を分離する
- 参照はページネーションしたり
- repository をドメインモデルで受け取って上限チェックとカート追加する?
- テストではモックが必要 = 純粋性は失われる
- 遅延ロードを使う
- 意図しないところでクエリが流れるので難易度高め
- すべてメモリにロードしないが参照系では必要になる
- 純粋性+性能
- 性能を保ちつつ完全性と純粋性のメリットを享受したい
- 状態の変更やチェック (不変条件) をドメイン層に実装する
- 状態によって定義される振る舞いは違うはず
- 状態によって型を分ける
- 高凝集
- 複数の責務が混ざってるものは高凝集ではない
- 異なる振る舞いをするものは異なるものと見なす
- 型で表現する
- 複雑さ (異なる概念) を型で表現するのが重要
- 重複してるかもしれないユーザーと重複していないことが保証されるユーザーは別の概念 (定義される振る舞いが異なる)
- ユーザー重複チェックは重複してるかもしれないユーザーの振る舞い
- ユーザー登録は重複していないことが保証されるユーザーの振る舞い
- ↑を型で表現する
- 重複してるかもしれないユーザーと重複していないことが保証されるユーザーは別の概念 (定義される振る舞いが異なる)
- Parse, don't validate
- バリデーションと同時に型を変換する
- 失敗可能性を前へ
- Always-Valid Domain Model
- made functional
- ユースケースの1ステップを function で表す
- 構造が同じでも振る舞いが違うなら型を分ける