【问题标题】:Should a Domain Entity call a repository?域实体应该调用存储库吗?
【发布时间】:2018-06-02 11:24:04
【问题描述】:

我正在设计一个运输应用程序并尝试使用 Clean Architecture 和 DDD。在领域层的核心深处,我们有许多可配置的业务规则。例如,有用于确定货物的最佳承运人、确定运输方式、确定付款类型等的业务规则。每个业务规则都从数据库中选择数据,因此我计划使用 BizRule 存储库。问题是,根据我对 DDD 原则的理解,域实体(例如 Shipment)不应该调用存储库(例如 BizRuleRepository)。用例层应该是调用存储库的层。如果我采用这种方法,那么我将不得不将许多复杂的业务规则移至用例层,我​​不确定这是否是最好的方法。在这种情况下,进行异常并让域实体调用存储库是否有意义?提前谢谢你。

【问题讨论】:

    标签: domain-driven-design ddd-repositories clean-architecture


    【解决方案1】:

    如果只是为了阅读它应该没问题,也许它可以更简洁地拥有一个接口/服务(也只有一种方法),向您的商店表达所需的查询,将您的实体与存储库分离。 通过这种方式,您可以轻松地在测试期间模拟查询,并且将来可以在其自己的类中轻松改进查找方法(或者您也可以为查找传递不同的策略/实现)。

    当您使用存储库写入实体内部时会出现问题。

    【讨论】:

      【解决方案2】:

      域实体应该调用存储库吗?

      一般来说,没有;实体(这是一个关注点)直接与存储库(这是管道)进行通信是没有意义的。

      埃文斯在组织他的书时,将这些想法分配到不同的章节

      • 用软件表达的模型 -- 描述实体
      • 域对象的生命周期 -- 描述存储库

      这是语言的问题;存储库通常具有集合或持久性语义,它们(通常)不是域的普遍存在的语言的一部分。

      也就是说,有一个漏洞; 领域服务可以使用通用语言描述数据检索,并将这项工作委托给应用程序或基础设施服务。

      所以(暂时假设业务规则是一个 概念),您将有一个域实体知道它需要 哪个 业务规则,以及一个域知道如何检索业务规则的服务,然后知道如何使用它的实体。

      如果业务规则不是领域概念,那么一些工作从实体转移到领域服务,但模式的核心保持不变——实体将参数传递给服务,服务返回实体理解的域值,实体决定如何在其当前处理中应用该值。

      我们可以通过引入额外的间接级别来解决任何问题

      这有点像一场空壳游戏;在幕后,我们仍在使用管道;但是领域模型只看到瓷器。

      当您想要对域逻辑进行单元测试而不拖入整个管道依赖项时,额外的间接层非常方便:您将域服务替换为测试替身。

      【讨论】:

      • 如果我需要调用数据库查询进行验证,我应该把这个调用放在哪里?可能进入存储库,但是什么将存储库..应用程序服务或域服务?
      • softwareengineering.stackexchange.com/a/318710/155881 这个答案说:'一个实体能够使用存储库来检索另一个实体或检索一些无法轻易保存在内存中的特定信息并没有错。这就是为什么 Repository 是 Evans 书中的关键概念的原因。'
      猜你喜欢
      • 1970-01-01
      • 2010-11-24
      • 2011-05-24
      • 2011-09-23
      • 2016-04-28
      • 2011-09-28
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多