8

通常可以接受一个存储库可以访问另一个存储库吗?特别是在这种情况下,我有一个聚合根,它使用另一个聚合根来确定要添加的实体。它符合项目/项目类型关系。项目类型是聚合根的原因是它们可以在任何单个项目范围之外的管理工具中单独维护。

如果它确实重要,我只是通过存储库工厂实现创建我的存储库实例,所以我不会直接通过具体的类名创建它。聚合体在任何时候都不知道存储库。

编辑 - 更多信息:

具体实现是我们可以将图像附加到文档中。我们不仅可以管理文档上的图像,而且还有不同类型的图像(例如,类型被定义为如何实现,而不是扩展)。文档集合是系统中使用这些图像的少数几种其他对象之一,它们并不都使用相同的类型。虽然我们确实在域服务中附加了规则,但这更具体地适用于构建文档聚合。在构建聚合时,我们有五个特定类型的图像,以及其他两种类型中的一个。我们单独提取这些,因为它们存储在聚合中的单独列表中。验证不是问题,而是在组装文档时限制正在评估的图像类型。

4

2 回答 2

6

我想这归结为您尝试做的事情。如果这是一种验证步骤(例如,删除所有项目类型已过期的项目),您可能会认为它属于服务层或规范。从您使用的语言(即“确定要添加的实体”)来看,似乎建议使用后者,尽管如果没有更多细节很难说。

我想从某种角度来看,你没有真正的理由不能(我绝不是最纯粹的超级 DDD),特别是因为一个 Item 及其类型可以被视为一个聚合根并且它只是实现细节您需要提供一个可以防止的管理控制台。

从另一个角度来看,它似乎确实表明您的聚合根之间存在模糊,这可能表明两种不同的上下文在起作用。例如,有人可能会争辩说,管理工具为您的主应用程序形成了一个单独的有界上下文,因此 Item 类型是聚合根的情况并不真正适用。例如,管理工具可能只关心项目类型(而不是项目),而您的主应用程序可能将项目类型视为一个值对象而不是实体。

更新

正如您提到的组装文档,这似乎是可以正确组装有效实体的工厂类的责任(工厂可以使用图像类型存储库)。存储库应该(在我看来)公开查询和添加操作,而不是配置实体的逻辑(除了可能从持久性中恢复)。

于 2009-08-26T19:20:38.590 回答
1

一个仓库使用另一个仓库不符合 DDD 的原则。如果您需要来自一个聚合根的数据来对另一个聚合根执行某些操作,您可以检索第一个根(在应用程序服务层或可能在域服务中),然后将该数据传递到相关聚合根的公共 api ,或者在使用单独工厂的聚合根创建的情况下,进入工厂的公共 api。

聚合根定义了事务边界,其中的数据应在事务上保持一致。这种对事务一致性的期望不应扩展到该边界之外的任何事物。如果您有一个依赖于另一个存储库的存储库,那么您的一个聚合的状态在事务上依赖于另一个聚合的状态,这意味着这些“聚合根”实际上都不是聚合根。

此外,如果您需要更改一个聚合的状态以影响另一个聚合的状态,您应该为此使用域事件,这会强制根之间的 最终一致性。

于 2019-10-13T13:58:42.090 回答