5

让我们考虑典型的OrderOrderItem示例。假设OrderItemOrder Aggregate 的一部分,它只能通过 Order 添加。因此,要向 Order 添加新的OrderItem 我们必须通过 Repository 加载整个 Aggregate,向Order对象添加新项目并再次持久化整个 Aggregate。

这似乎有很多开销。如果我们的Order有 10 个OrderItems怎么办?这样,仅仅添加一个新的OrderItem,我们不仅要读取 10 个OrderItems,而且我们还应该重新插入所有这 10 个OrderItems。(这是 Jimmy Nillson 在他的 DDD 书中采用的方法。每次他想要持久化一个 Aggregate 时,他都会清除所有子对象,然后再次重新插入它们。这可能会导致其他问题,因为孩子的 ID 是由于数据库中的 IDENTITY 列,每次都更改。)

我知道有些人可能会建议在聚合根中应用工作单元模式,以便跟踪已更改的内容并仅提交这些更改。但这违反了持久性无知 (PI) 原则,因为持久性逻辑正在泄漏到领域模型中。

有没有人考虑过这个?

莫什

4

3 回答 3

1

我不是 100% 确定这种方法,但我认为应用工作单元模式可能是答案。请记住,应该在应用程序或域服务中完成任何事务,您可以使用您已更改的聚合中的对象填充工作单元类/对象。之后,让 UoW 类/对象发挥作用(当然,在某些情况下,构建适当的 UoW 可能很困难)

以下是来自此处的工作单元模式的描述:

工作单元跟踪您在可能影响数据库的业务事务期间所做的一切。完成后,它会计算出根据您的工作更改数据库需要做的所有事情。

于 2014-03-22T21:30:06.647 回答
1

这不一定是问题,一些 ORM 支持惰性列表。例如,您可以加载订单实体并将项目添加到 Details 集合,而无需实际实现该列表中的所有其他实体。

我认为 N/Hibernate 支持这一点。

如果您正在编写自己的没有任何 ORM 的实体持久性代码,那么您非常不走运,您将不得不重新实现与 ORMappers 免费提供的相同的脏跟踪机制。

于 2010-05-06T08:56:16.167 回答
1

必须从数据库加载整个聚合,因为 DDD 假定聚合根确保聚合边界内的一致性。要检查这些规则,必须加载所有必要的数据。如果要求特定客户的订单价值不超过 100000 美元,则聚合根(订单)必须在持久更改之前检查此规则。这并不意味着必须加载所有现有项目并总结它们的价值。订单可以维护预先计算的现有项目的总和,这些总和会在添加新项目时更新。这种检查业务规则的方式只需要在添加新项目时加载订单数据。

于 2010-05-06T14:34:22.683 回答