DDD:通过其标识引用聚合根内的实体

Ben*_*min 9 language-agnostic entity identity domain-driven-design aggregateroot

当我们只从URL参数获取其身份时,我一直在找到引用聚合根内部实体的正确方法.我问过一个最后关注价值对象的问题,所以我从这里开始另一个例子.

假设我们要修改一个OrderLine内部Order:

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

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

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);
Run Code Online (Sandbox Code Playgroud)

但是,我对将责任留给订单以便通过Id检索自身部分的想法感到不自在.我对这个主题的看法是,在域内,我们应该只与对象交谈,而不是与ID 交谈.Ids不是无处不在的语言的一部分,我相信它们应该存在于域之外,例如在Controller中.

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

Order order = orderRepository.find(orderId);
OrderLine orderLine = em.find(OrderLine.class, orderLineId);
order.updateQuantity(orderLine, 2);
Run Code Online (Sandbox Code Playgroud)

虽然我不喜欢直接与实体管理器交互的想法.我觉得我绕过了Repository和Aggregate Root职责(因为我可能会直接与OrderLine交互).

你是如何解决这个问题的?

Dmi*_*try 13

在我看来,这种方法没有错:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);
Run Code Online (Sandbox Code Playgroud)

orderLineId是一种"本地身份".它特定于聚合根,并且在它之外没有意义.您不必将其称为"id",它可以是"订单行号".来自Eric Evan的书:

边界内的实体具有本地身份,仅在AGGREGATE内是唯一的.

...只能使用数据库查询直接获取AGGREGATE根.必须通过遍历关联找到所有其他对象.