2

我无法理解如何访问聚合根的子实体。从我上一个问题的答案中,我现在了解到我需要识别模型的聚合根,然后只设置处理这些根对象的存储库。

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

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

4

2 回答 2

1

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

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

然后,在控制器中,我只需从 OrderRepository 检索订单,然后从那里访问适当的项目。

综上所述,我同意 Arnis 的观点,即您根本不必总是遵循这种模式。这是一个个案,你应该在做之前评估权衡。

于 2011-05-18T13:55:06.663 回答
0

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

我个人不尝试抽象持久性(我不使用存储库模式)。另外 - 我不按照聚合根原则遵循存储库。但我确实将域模型与持久性隔离开来。

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

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

在思考这个问题时,最好记住得墨忒耳法则关键是 -只有当我们明确想要隐藏内部时才应该应用它。在您的情况下 - 我们不想隐藏订单项目。

所以 - 利用我们知道实体 ID 是全局唯一的事实(而不是仅在 Order 上下文中唯一),这只是一个捷径,直接检索它们没有任何问题。


有趣的是——这可以向前推进。
甚至行为封装也可以而且应该放宽

例如 - 它比拥有更有orderItem.EditComments("asdf")意义order.EditOrderItemComments(order.OrderItems[0], "asdf")

于 2011-05-18T13:28:49.010 回答