2011-05-17 75 views
2

我无法理解如何访问聚合根的子实体。从我的previous question的答案我现在明白,我需要确定我的模型的聚合根,然后只设置处理这些根对象的存储库。ASP.NET MVC Action方法如何访问聚合根的子实体?

所以说我有一个包含项目的订单对象。项目必须存在于Order中,因此Order是聚合根。但是如果我想在我的网站中包含OrderItem详细信息页面呢?此页面的URL可能类似于/ Order/ItemDetails/1234,其中1234是OrderItem的ID。然而,这将需要我直接通过ID检索项目,并且因为它不是一个聚合根,我不应该有一个OrderItemRepository可以通过ID来检索OrderItem。

因为我想使用独立于Orders的OrderItems,这是否意味着OrderItem实际上不是Order的集合,而是另一个聚合根?

+0

我会考虑OrderItem作为一个值对象,因为它没有订单的上下文没有真正的mening。 – alexn 2011-05-18 07:30:11

+0

OrderItem是一个实体而不是值对象,因此它必须具有标识。从业务角度来看,2个同等数量产品的OrderItems可能不相等 – xelibrion 2011-05-18 09:25:36

+0

您也可以将您的问题发布到Google DDD/CQRS组,该组具有非常活跃的社区https://groups.google.com/forum/#!forum/dddcqrs – xelibrion 2011-05-18 09:27:54

回答

0

在你的情况下,我会直接通过URL /OrderItem/1234检索OrderItem。

我个人不试图抽象持久性(我不使用库模式)。另外 - 我不遵循每个聚合根原则的存储库。但我确实从持久性中分离出领域模型。

主要原因是 - 完全抽象持久性机制几乎是不可能的。这是一个漏洞抽象(例如,尝试指定存在于没有污染的存储库API下面的ORM的加载/延迟加载)。

另一个原因 - 报告数据的方式并不重要。报告部分很无聊而且相对不重要。应用程序的真正价值在于它可以做什么 - 流程的自动化。所以更重要的是你的应用程序如何表现,它如何保持一致,对象如何相互作用等。

想到这个问题时,最好记住Law of Demeter。重点是 - 如果我们明确想要隐藏内部消息,则应该应用只有。在你的情况下 - 我们不想隐藏订单项目。

因此 - 利用我们知道实体ID是全局唯一的事实(与订单环境中的唯一对立)相反,这只是一个捷径,直接检索它们没有任何问题。


有趣的是 - 这可以推进。
即使行为封装可以和should be loosened up too

E.g. - 拥有orderItem.EditComments("asdf")order.EditOrderItemComments(order.OrderItems[0], "asdf")更有意义。

1

我不知道你的商业规则,当然,但我想不出你会有没有订单的订单项目的情况。并不是说你不想单独“与一个人合作”,但它仍然必须有一个订单,imo,而订单则负责这种关系;例如您可以通过添加或删除订单中的项目来表示所有这些。

在这种情况下,我通常仍然需要通过订单访问这些项目。这是很容易设置,在URL我会做/订单/ 123 /项目/ 456。或者,如果物料订单存储/重要(通常至少通过输入订单间接存储),您可以执行/ order/123/item/1来检索订单上的第一个物料。

在控制器中,我只是从OrderRepository中检索订单,然后从那里访问相应的项目。所有这些说法,我确实同意瓦特/阿尔尼斯,你并不总是必须遵循这种模式。在做这件事之前,您应该评估权衡,这是一个逐案的事情。

相关问题