存储库类应该进入哪个层?域名或基础设施?
答案 0 :(得分:17)
存储库接口是域的一部分。接口的实际实现应该是基础结构的一部分。
答案 1 :(得分:5)
存储库实现类以及单独的接口(如果存在)应该进入域层。
原因在于分层架构中应遵循的基本规则:较低层不得依赖于较高层。
如果我们接受此规则(否则它不是分层架构),那么将存储库实现放入基础架构层将使其依赖于域层,因此违反了分层的基本规则。
例如,当我们创建一个新的域实体时,我们将它放在域层中;并且由于存储库(其接口及其实现)必然不可避免地依赖于域实体,这意味着存储库也必须进入域层。否则,只要在域层中添加/删除/修改域实体,我们就会更改基础结构层。
其他问题,例如保持域层"清洁"并且不依赖于持久性细节,可以并且应该通过使用域层内实现的适当基础结构服务来实现。例如,在Java中,我们可以使用JPA来实现具有非常少的代码的存储库,并且没有SQL / JDBC或特定于数据库的代码(使用JPA实现存储库真的是一个好主意是另一种讨论;无论如何,JPA实体无论如何都会使用JPA注释。
答案 2 :(得分:2)
我想这取决于你将如何依赖它们。
问题是 - 您是否允许自己从域内使用存储库?
如果是这样 - 那么你就被迫把它们放进去了。
我自己喜欢把它们放在域外。所以 - 典型的生命周期看起来像这样=>
UI =>控制器=>从repo =>检索聚合根通过聚合root =>调用逻辑如果创建了新的聚合根,则将其添加到repo。
有时控制器调用应用程序服务除了检索root和调用函数之外还执行一些其他操作。但想法是一样的 - 领域对持久性一无所知。
虽然(正如我所看到的)将repos放入域中(或者至少是对它们的抽象)没有任何问题,它会让你的域更加了解持久性。有时,这可以解决问题,但一般来说 - 这肯定会使您的域更复杂。
使用对你来说更自然的东西,并随时准备好改变你的方式。
答案 3 :(得分:0)
存储库类实现应位于基础设施层。存储库接口应该在服务层。
域层应该对存储库一无所知。 DDD 的战略模式规定领域层应该始终与概念模型同步。这意味着域层应该将众所周知的域过程转换为代码,反之亦然。领域流程是您的领域专家应该非常了解的。领域专家对存储库一无所知。
另一种思考方式。让我们假设我们将存储库或存储库的接口放入域层。 IE。现在我们在域层代码中有存储库概念。此外,领域层应该与领域的概念模型同步。那么,让我们问问自己在概念模型中存储库的表示是什么。正确答案是概念模型中没有存储库。因此,存储库不能在域层。
总而言之,我仍然遇到在域层中有存储库的项目,并且项目的工程师仍然称其为 DDD 实践。我认为这里的问题是人们并没有过多关注位于 DDD 核心的战略模式,而只是玩弄可能会稍微简化编码工作的战术模式。