9

当我们只从 URL 参数中获取它们的身份时,我一直在寻找正确的方法来引用位于聚合根中的实体。我问了一个先前的问题,该问题最终集中在value objects上,所以我从这里的另一个示例开始。

假设我们要修改 anOrderLine内部Order

  • 用户转到一个页面,他可以在其中看到订单摘要及其所有订单行。
  • 用户单击订单行旁边的编辑按钮。
  • 他被引导到edit-order-line?orderId=x&orderLineId=y

现在,如果我需要更新 OrderLine 中的数量,我可以这样做:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);

但是,我对将责任留给教团通过 Id 检索其自身的部分的想法感到不太自在。我对这个主题的看法是,在领域内,我们应该只与对象交谈,而不是与 Ids 交谈。ID 不是通用语言的一部分,我相信它们应该存在于域之外,例如在控制器中。

我会对以下内容更有信心:

Order order = orderRepository.find(orderId);
OrderLine orderLine = em.find(OrderLine.class, orderLineId);
order.updateQuantity(orderLine, 2);

虽然我也不喜欢直接与实体管理器交互的想法。我觉得我正在绕过 Repository 和 Aggregate Root 职责(因为我可以直接与 OrderLine 交互)。

你如何解决这个问题?

4

3 回答 3

13

在我看来,这种方法没有任何问题:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);

orderLineId是“本地身份”。它特定于聚合根,在它之外没有意义。您不必将其称为“id”,它可以是“订单行号”。从埃里克埃文的书中:

边界内的实体具有本地标识,仅在聚合中是唯一的。

...只有 AGGREGATE 根可以通过数据库查询直接获得。所有其他对象必须通过关联的遍历找到。

于 2011-09-05T17:10:31.190 回答
1

OrderLineId 究竟是什么?它没有任何意义。您正在更新产品的数量,这就是应该用作 id 的内容。

Order order = orderRepository.find(orderID);
order.updateQuantity(productID, 2);
于 2011-11-20T18:12:49.540 回答
0

聚合根绑定到上下文,在您的上下文中,订单AR,因此可以直接更新它,因为您直接公开它,如果该代码影响它们应该存在于订单 AR 中的其他实体。

如果您想要一种更纯粹的方法,您要么必须在 AR 中创建一个 findByOrderId 并完全加载它,要么在您的应用程序中公开 OrderLine 和 OrderId(然后使用您的第二种方法)。

于 2011-09-05T16:51:55.160 回答