2011-05-17 65 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中檢索訂單,然後從那裏訪問相應的項目。所有這些說法,我確實同意瓦特/阿爾尼斯,你並不總是必須遵循這種模式。在做這件事之前,您應該評估權衡,這是一個逐案的事情。

相關問題