Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic DDD:通过其标识引用聚合根中的实体_Language Agnostic_Domain Driven Design_Entity_Identity_Aggregateroot - Fatal编程技术网

Language agnostic DDD:通过其标识引用聚合根中的实体

Language agnostic DDD:通过其标识引用聚合根中的实体,language-agnostic,domain-driven-design,entity,identity,aggregateroot,Language Agnostic,Domain Driven Design,Entity,Identity,Aggregateroot,我一直在寻找正确的方法来引用位于聚合根中的实体,而我们只从URL参数获取它们的标识。我问了一个以价值对象为中心的例子,所以我从另一个例子开始 假设我们要在订单中修改订单行: 用户进入一个页面,可以看到订单摘要及其所有订单行 用户单击订单行旁边的编辑按钮 他被引导到编辑订单行?orderId=x&orderLineId=y 现在,如果我需要更新订单行中的数量,我可以执行以下操作: Order order = orderRepository.find(orderId); order.update

我一直在寻找正确的方法来引用位于聚合根中的实体,而我们只从URL参数获取它们的标识。我问了一个以价值对象为中心的例子,所以我从另一个例子开始

假设我们要在
订单
中修改
订单行

  • 用户进入一个页面,可以看到订单摘要及其所有订单行
  • 用户单击订单行旁边的编辑按钮
  • 他被引导到
    编辑订单行?orderId=x&orderLineId=y
现在,如果我需要更新订单行中的数量,我可以执行以下操作:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);
然而,我不太赞成将责任交给通过Id检索自身部分的订单。我对这个主题的看法是,在域内,我们应该只与对象交谈,而不要与Id交谈。ID不是无处不在的语言的一部分,我相信它们应该存在于域之外,例如控制器中

我会对这样的事情更有信心:

Order order = orderRepository.find(orderId);
OrderLine orderLine = em.find(OrderLine.class, orderLineId);
order.updateQuantity(orderLine, 2);
尽管我也不喜欢与实体经理直接互动的想法。我觉得我绕过了存储库并聚合了根职责(因为我可以直接与订单行交互)


如何解决这一问题?

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


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

我认为这种方法没有错:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);
orderLineId
是一个“本地标识”。它是特定于聚合根的,在它之外没有意义。您不必称之为“id”,它可以是“订单行号”。书中:

边界内的实体具有本地标识,仅在内部唯一 总量

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


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

Order order = orderRepository.find(orderID);
order.updateQuantity(productID, 2);

我认为Benjamin的问题是关于从聚合根目录导航到他想要更新的订单行的最佳方式。让应用程序代码在订单行中迭代似乎与应用程序代码有冲突。感谢您的澄清,我承认我没有使用上面发布的“仅在聚合中唯一”Dmitry,现在想知道我是否遇到过这样的实现。我同意-orderLineId不一定是指您的DB id,它可以是唯一标识此单个聚合中的订单的任何内容(行的序号或orderNo/LineNo形式的聚合代码)。按此标识符查找特定行是订单的责任。这种方法不会影响AR的接口吗?如果AR只有2个实体,每个实体有2个方法,AR需要4个方法来支持实体,这是理想的方法吗?这取决于,有人会说,当你有这么大的总量时,你已经有问题了。这可能只是一个迹象,表明您需要重新考虑对较小集合的设计,请参见:这是一个相关的反对意见,尽管在我们的应用程序中,您的购物车中可能有多次相同的产品,选择了不同的选项(考虑一件绿色t恤和一件红色t恤;如果我想专门更新绿色t恤的数量,我不想通过完整的选项数组来匹配正确的订单行:颜色、尺寸……因此,在这一点上传递
orderLineId
对我来说最有意义).很公平。虽然我可能仍然会选择更自然的密钥,例如productID+任何其他使其唯一的密钥。但当然,OrderLineId仍然有效。