简短回答:尽管它应该是域层中基础设施的任何依赖项,但为了KISS https://en.wikipedia.org/wiki/KISS_principle, you may这样做。如果你想成为 DDD 纯粹主义者,你可以定义一个CustomerRepository
接口以及基础设施中实现这两个接口的实现。
又长又无聊的答案:一般来说,域不应该关心或了解基础设施,因为它不应该依赖于其他层(基础设施、应用程序、表示或您正在使用的任何体系结构)。遵循这条规则会产生更干净的架构。
特别是,域不应该关心持久性,它的行为应该像在内存中运行一样。从领域的角度来看,实体会发生变异,仅此而已,不需要持久性。
域代码的写入端实际上不需要持久性。当聚合执行命令时,它们已经完全加载。执行命令后,聚合仅返回更改或新状态。聚合本身并不保留更改。它们是纯净的,没有明显的副作用。
我们,架构师,需要持久性,因为我们需要确保数据在重新启动之间保持不变,并且我们可以同时在多台机器上运行相同的代码。
然而,域代码还有另一个需求,特别是域的读取和响应端(Sagas/进程管理器)。域的这些组件需要查询和过滤域实体。 Readmodels 需要将实体返回给调用者,Sagas/Process 管理器需要正确识别向其发送命令的正确聚合。
解决方案是仅在域层中定义接口并在基础设施中实现。通过这种方式,域拥有接口,因此,根据依赖倒置原则 https://en.wikipedia.org/wiki/Dependency_inversion_principle,它不依赖于基础设施。
在你的情况下,虽然域层取决于某物从 Spring 框架的基础设施部分来看,某物只是一个接口。它仍然是对 JPA 的依赖,因为您的域将使用它不拥有的方法,但在这种情况下 KISS 可能更重要。
另一种方法是定义一个不扩展 JpaRepository 的接口,并在基础设施中实现该接口和 JpaRepository 接口。
哪种解决方案取决于您:更多代码重复但更少依赖,或者更少代码重复但更多对 JPA 的依赖。