如何选择DDD Aggregate?

第4章(第一个草图) 中使用C#中的示例应用域驱动设计 第4章(第一个草图)并发冲突检测很重要我不明白为什么作者选择了这个聚合。客户有他自己的聚合和订单有他的自己的聚合。

我认为客户应该参考他的订单。

订单只与客户有身份。 我没有看到一个情况是通过他的id从数据库获得订单。 但是如果我应用这个逻辑,那么在我的域模型中,我几乎没有包含所有实体和值对象的复杂聚合。 我不想要这个。

从数据库获取客户时,它不会直接加载他的订单(延迟加载)。 所以这不是一个论点。

如果客户在不同的场景中使用,那么最好清除客户的参考仅在一个场景中有用。 我猜这是为订单汇总并对其订单进行“间接参考”的一个原因。

那么选择聚合的真正原因是什么?

我有另一个误解。 订单有更多OrderLine。 OrderLine有一个产品。 为什么OrderLine允许在聚合顺序之外引用对象(Product)?

我认为客户应该参考他的订单。

与存储库查找实现关系是对象引用的替代方法。 在客户和订单之间存在关系的这些类型的情况下,它很有用,但实现为对象引用没有意义。 出于某些原因,这是如此。 一个是加载与客户关联的所有订单可能是不可行的。 即使使用延迟加载,您通常也需要一个分页集合。 另一个原因是作者将并发冲突检测称为并发冲突检测,也称为事务一致性。 没有涉及与客户相关的所有订单的任何行为,并且引用所有订单是不必要的。

从数据库获取客户时,它不会直接加载他的订单(延迟加载)。 所以这不是一个论点。

延迟加载可能会有问题 。 主要原因是难以实现,缺乏实施的灵活性以及降低推理代码的能力。

那么选择聚合的真正原因是什么?

聚合应该是一致性边界。 换句话说,聚合界定了一组实体和值对象,这些实体和值对象必须在与聚合相对应的行为下保持一致。 这既有业务上的影响,也有技术上的影响。 有关详细信息,请参阅Effective Aggregate Design 。

为什么OrderLine允许在聚合顺序之外引用对象(Product)?

通常,订单行应引用表示订购产品的值对象,而不是对实际产品实体的引用。 这部分是由于讨论的聚合约束,也是因为订单是一个事件,应该是不可变的。