本記事は、 DDD-Community-Jp Advent Calendar 2020の5日目です。
はじめに
DDD-Community-JP(以下、DDDCJ)内では架空の会議室予約のドメインを考え、C#で実装するモデリング会を隔週ペースで行っています。
この勉強会の中で実装をしていたときに、
リポジトリのインターフェースってどこに置く?
という疑問が出てきました。
Repository Interface はどこに書く?って話と、どういうフォルダ名にする?って話が出た。
— 98lerr (@98lerr) November 22, 2020
どこっていうと大きく二択。
- domainに置く
- Applicationに置く
「集約の操作なんだからDomain」というのと「集約をどう扱うかはDomainの関心外」というので考え方分かれる。#ModelingKai
結局の所、どちらに正解、不正解はない
議論をしていた時には、大別すると二種類のパターンがあるよね、という話がありました。
- ドメイン層
- ユースケース/アプリケーション層
結論としては、そのプロジェクトでちゃんとチーム内で取り決めて、開発していければ問題はないと思います。
(プロジェクトによってマッチするしないはあると思いますので)
ただ、そこに置くと決めた背景や考え方を、それぞれ理解しておくこと自体に、
非常に価値があると思っておりますので、少しまとめてみます。
各レイヤーの責務
まずは前提合わせとして、各レイヤーはどんなことをするのかを書いておきます。
- プレゼンテーション層
- APIの値の受け取り、バリデーション、変換
- ユースケース(アプリケーション)層
- ユースケースの実現と表現
- ドメイン層
- ビジネスにおけるロジック、計算判断
- インフラストラクチャ層
- データベースへのアクセスなど
ドメイン層の持ち物だよね、派
- リポジトリのメソッドが唯一、「集約の範囲」をコードで定義している、という考え方
- リポジトリは集約単位のみ永続化層との入出力をしないので、この「集約の範囲」を明示するのは、ドメイン層の重要な知識の1つという考え方
- 「集約の範囲」 → 集約は強い整合性が保たれる範囲とか境界
- 「RDBのトランザクションも集約と同じ境界」であること。
- 実装上で考えると、ドメインサービスからリポジトリを参照したいことを考えたい時に、ユースケース層にインターフェースが置いてあると参照できなくなって困る
- 集約と同じパッケージ内に置いておかないと、気づかない人もいる
ユースケース/アプリケーション層の持ち物だよね、派
- リポジトリをそのままドメインオブジェクトと呼ぶのに、違和感がある
- だから外界(ドメイン層の外)とのやり取りをするリポジトリは、ユースケース層に置いておきたい
- ドメイン層に置きたい理由の一つであった、ドメインサービス内でリポジトリを使うことに関しては、作らないように取り決めしておく
このユースケース層に置いた方が良いという考え方につきましては、別記事で @t2-kob さんに、書いて頂こうと思っております。
→書いて頂きました
なぜリポジトリのインターフェースを UseCase/Application 層に置きたいと考えるか? (Advent Calendar 2020 アンサー編) - Qiita
所感
話を聞いていますと、「リポジトリをドメインオブジェクトとして扱うのか、それ以外の何かとして考えるのか」という捉え方の違いで、どこに置くのかというのが分かれてそうな気がしました。
個人的には、リポジトリはドメインオブジェクト(ではあるけど、直接モデルを表さない補助的なもの)だと思っているので、
リポジトリのインターフェースがドメイン層の中に置いてあるのは、自然だなと感じています。
ただ、ユースケース層に置きたいという話もわかるため、
自分の意見を絶対だと思わず、相手の意見の背後にある考え方を聞くのはあらためて大事だと感じました。
おわりに
ざっと2パターンを出してみましたが、
私はこの層に置くよ/やったことがあるよ、みたいな意見もあると思います。1
ぜひこういう考え方もあるよ、みたいなのがあればぜひ教えて頂けたらと思っております…!
2020/12/06 追記
DDDCJの中で、この話をしましたところ、
エヴァンス本的には「知識、影響、または活動の領域」と定義されているけど、その「領域」をどのように線引するのかが、あまり語られてないよね、という話がありました。
「ドメインに含まれるものは何?」という話をした上で、その前提から上のような「リポジトリのインターフェースってどこに置く?」みたいな話に派生していくのだと。
このお話を聞いて、自分はドメインに含まれるものは、アプリケーションの適応対象となる業務になるのだろうという認識を持っていますが、その中に記録の範囲が入るかというと、また悩ましい感じがしています。
ただ、システムにあるデータを意味のあるデータとしてまとめ、記録、取り出してドメイン層の中で扱えるようにする、という意味では、ドメイン層の中に置いておくのが、いまのところ収まりが良いとは、個人的にはしています。
参考資料
-
そもそもな話、置く場所なんてどこかに一箇所に決めればそれでいいよ、という意見もあるかもしれません ↩