我正在设计运输应用程序并尝试使用Clean Architecture和DDD。在域层的核心深处,我们有许多可配置的业务规则。例如,存在用于确定货物的最佳承运人,确定运输模式,确定支付类型等的业务规则。每个业务规则从数据库中选择数据,因此我计划使用BizRule存储库。问题是根据我对DDD原则的理解,域实体(例如Shipment)不应该调用存储库(例如BizRuleRepository)。 Use Case层应该是调用存储库的层。如果我采用这种方法,那么我将不得不将许多复杂的业务规则移到Use Case层,我不确定这是否是最好的方法。在这种情况下,做出异常并让域实体调用存储库是否有意义?提前谢谢。
答案 0 :(得分:4)
域实体是否应该调用存储库?
一般来说,没有;对于实体(这是域关注点)直接与存储库(管道)进行通信,它没有意义。
埃文斯在组织他的书时,将这些想法分配到不同的章节这是一个语言问题;存储库通常具有集合或持久性语义,这些语义不是(通常)域的无所不在的语言的一部分。
那就是说,有一个环洞; 域服务可以使用普遍存在的语言描述数据检索,并将该工作委托给应用程序或基础结构服务。
所以(假设目前业务规则是域概念),您将拥有一个知道所需的业务规则的域实体,以及一个域知道如何检索业务规则的服务,然后知道如何使用它的实体。
如果业务规则不域概念,那么一些工作从实体转移到域服务,但模式的核心保持不变 - 实体将参数传递给service,该服务返回实体理解的域值,实体决定如何在当前处理中应用该值。
我们可以通过引入额外级别的间接来解决任何问题
这是一场贝壳游戏;在封面下,我们还在使用管道;但域名模型只能看到瓷器。
当您想要在不拖动管道依赖项的整个世界的情况下对单元测试域逻辑进行单元测试时,额外的间接层可以非常方便:您使用测试双重替换域服务。
答案 1 :(得分:0)
如果只是为了阅读它应该没问题,也许它可以更清洁,有一个接口/服务(也只有一个方法)表达你的商店所需的查询,将你的实体与存储库分离。 通过这种方式,您可以在测试期间轻松模拟查询,并且将来可以在自己的类中轻松改进查找方法(或者您也可以为查找传递不同的策略/实现)。
使用存储库编写实体内部时会出现问题。