为什么存储库仅用于域驱动设计中的聚合?

Han*_*tri 6 oop domain-driven-design repository aggregateroot aggregates

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

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

(如果这只是一个事实,即所有普通实体都可以看作是零孩子的集合根,请告知我这个问题,这个问题可以埋没.)

Voi*_*son 9

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

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

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

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

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

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

,您确实看到用于除聚合之外的事物的"存储库" - 存储库也可用于查找模型状态的缓存视图.诀窍是视图不支持修改.在Evans描述的方法中,每个实体都有一个表示其所有角色的表示.在CQRS中,实体可能在每个角色中具有不同的表示,但通常只有一个支持修改实体的角色.

  • 例如:聚合的订单和行项目。如果我想更改项目状态,我必须通过订单 ID 查询订单及其行项目,通过订单实体更改项目状态,最后调用聚合存储库进行保存。我对吗 ? (3认同)

Con*_*enu 7

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