存储库类应该放在哪一层?领域层还是基础设施层?
存储库类应该放在哪一层?领域层还是基础设施层?
存储库的 接口 是领域的一部分。 接口的实际 实现 应该是基础设施的一部分。
我想这取决于您将如何依赖它们。
问题是 - 您是否允许自己从域内使用存储库?
如果是这样的话,那么您就被迫把它们放在里面。
我个人喜欢把它们放在域外。因此,某些东西的典型生命周期如下所示 =>
UI => 控制器 => 从存储库检索聚合根 => 通过聚合根调用逻辑 => 如果创建了新的聚合根,则将其添加到存储库中。
有时控制器会调用应用程序服务,除了检索根并在其上调用函数之外,还会执行一些其他操作。但思路是相同的 - 领域不知道持久性。
虽然(在我看来)在域中放置存储库(或至少它们的抽象)没有什么问题,但它会使您的域更加意识到持久性。有时这可以解决问题,但通常情况下 - 这肯定会使您的域更加复杂。
使用对您而言更自然的方式,并随时准备切换您的方式。
仓储实现类与其单独的接口(如果存在)应该放在领域层中。
原因是遵循分层架构中的基本规则:低层不应依赖高层。
如果我们接受这个规则(否则它就不是一个分层架构),那么将存储库实现放入基础结构层将使其依赖于领域层,从而违反了分层的基本规则。
例如,当我们创建一个新的领域实体时,我们将其放在领域层中;由于存储库(包括其接口和实现)不可避免地依赖于领域实体,这意味着存储库也必须放在领域层中。否则,在领域层中添加/删除/修改领域实体时,我们将更改基础结构层。
其他问题,例如保持领域层“干净”并独立于持久性细节,可以通过在领域层内部的实现中使用适当的基础设施服务来实现。例如,在Java中,我们可以使用JPA以非常少的代码实现存储库,并且没有SQL / JDBC或特定于数据库的代码(是否使用JPA实现存储库真的是一个好主意是另一种讨论;在任何情况下,JPA实体将使用JPA注释)。
实现仓储类应位于基础架构层。仓储接口应该在服务层中。
领域层不应了解仓储库。DDD的战略模式指出,领域层应始终与概念模型保持同步。这意味着领域层应将众所周知的领域过程转换为代码,反之亦然。而领域过程是您的领域专家应该熟悉的内容。领域专家对仓储库一无所知。
另一种思考方式是,假设我们将仓储库或仓储库的接口放入领域层中。也就是说,现在我们在领域层代码中有了仓储库的概念。此外,领域层应该与领域的概念模型保持同步。因此,让我们问自己仓库在概念模型中的表示是什么。正确答案是概念模型中没有仓库。因此,仓库不能在领域层中。
尽管如此,我仍然遇到了将仓库放在领域层中的项目,并且项目上的工程师仍然称其为DDD实践。我认为问题在于人们没有重视DDD的核心战略模式,而只是玩弄可能会稍微简化编码工作的战术模式。
AutoMapper
。你知道它是用来做什么的吗?“基础设施层在领域层之下”——这再次证明你对DDD一窍不通。领域层不应该依赖于任何东西——也就是说,在领域层之下没有任何东西。 - manymanymore