9

在 DDD 中,存储库用于执行聚合的序列化和反序列化,例如通过读取和写入数据库。这样,聚合可以包含更纯粹的业务逻辑,并且不会耦合到非特定领域的持久性策略。

但是,我想知道为什么存储库总是被描述为专门用于聚合。将它用于所有实体不是同样有动力吗?

(如果这只是一个事实,即所有普通实体都可以被视为具有零个孩子的聚合根,请通知我,这个问题可以被埋没。)

4

2 回答 2

13

我想知道为什么存储库总是被描述为专门用于聚合。将它用于所有实体不是同样有动力吗?

因为聚合是暴露给应用层的一致性边界。

也就是说,是的,存储库负责从数据存储中获取状态快照,并从中构建构成聚合的实体和值的图。

存储库的 API 只公开一个聚合根,因为它定义了一致性边界。我们不让应用程序到达图中的任意位置并进行更改,而是强制应用程序与根对象进行独占通信。有了这个约束,我们只需要查看一个地方以确保所有更改都满足业务不变量。

因此,无需为模型中的每种类型的实体开发存储库,因为不允许应用程序直接与模型进行交互。

换句话说,聚合中的实体是私有数据结构。我们不允许客户端代码直接操作实体,原因与我们不实现允许客户端通过 api 并直接操作指针的列表相同。

中,您确实会看到用于聚合以外的事物的“存储库”——存储库也可用于查找模型状态的缓存视图。诀窍是视图不支持修改。在 Evans 描述的方法中,每个实体都有一个单一的表示来履行其所有角色。在 CQRS 中,实体在每个角色中可能有不同的表示,但通常只有一个角色支持修改实体。

于 2017-09-27T16:46:18.207 回答
4

在 DDD 中有两种实体:聚合根和嵌套实体。正如@VoiceOfUnreason回答的那样,您不允许从聚合外部修改嵌套实体,因此不需要为它们建立存储库(通过“存储库”,我指的是用于加载和持久化实体状态的接口)。如果您被允许,它将破坏聚合的封装,这是 OOP 中最重要的事情之一。封装有助于丰富的领域,有很多模型非常适合 DDD。

于 2017-09-27T18:39:41.957 回答