サーバーサイドの実装でドメインモデル貧血ぎみなのもそうだけど、そもそもドメインモデルのあるべき状態がわからなくなっていた
そのとき次の記事で、あるべき姿と、あるべき姿にトレードオフがあるということがわかった
ドメインモデルのあるべき姿に完全性、純粋性があげられるが、これらトレードオフがあり両立が難しい場合があるよねという話
- 完全性:高凝集が達成され、コードの変更容易性が向上する
- 純正性:テスト容易性と移植性が向上する
例えば
「変更しようとしているメードアドレスが他のどのユーザとも重複してないこと」
をどこで実装するか(詳細は記事参照)
これはユーザーがもつメールアドレスなので、ユーザーに閉じ込めるようにしたいが、1ユーザの集約の範囲を超えるのでデーターベース精査が必要になる
このとき以下のようなトレードオフが発生する
- 完全性のためにUser内でやるようにしたら、別のレイヤーに依存するため純粋性が失われる
- 純粋性のためにアプリケーションレイヤー内でやるようにしたら、完全性が失われる
そのため、どちらか一方を選択しなければならない
もっというと、実開発ではアプリケーションの性能を優先させなければならない時もあるため、
実際はトリレンマになる
- 純粋性+完全性:純粋かつ完全なるドメインかもしれないが、遅くて使い物にならない
- 完全性+性能:簡単なことでも、複雑な仕掛けが必要
- 純粋性+性能:ドメイン層がテスト簡単に書けるが、ユースケースからテストを通さないとほとんど品質保証の意味をなさない
記事だと、純粋性を守る方が多いとのことだが、アプリケーションレイヤーでのビジネスルールのチェック漏れの懸念があるので工夫が必要とあると書かれている
例えば、GoFのMementoパターンを使ってビジネスルールのチェック済みの型を設ける方法で回避する実装が紹介されている
たしかにこれで、純粋性を守りつつ、チェック漏れを防ぐことができそう
感覚的に私も純粋性を守った方がシンプルかなと思うので、このやり方を検討してみる