2011-05-31 62 views
4

從哪裏可以得出聚合的複雜性?爲了澄清,如果我的聚合具有一個ObjectA列表,它具有一個ObjectB列表,它具有ObjectC列表,我的聚集是否應該負責檢索ObjectC?或者我應該考慮創建另一個聚合體來將這種複雜性降低到層次結構中的幾個級別?域驅動設計中的聚合根複雜度

回答

7

在大多數情況下,聚合的邊界應該是模型所需的一致邊界。這意味着,如果ObjectA或B或C的更改需要彼此一致,可能屬於同一個聚合。

複雜性(業務邏輯複雜性)應該通過識別域中的所有概念並在涉及的實體/ VOs中分離行爲來處理。

檢索複雜性(基礎結構複雜性)的對象應該由基礎結構處理,而不是由聚合處理。

總之,根據您的域名和您的一致性邊界建模AR,而不是爲了促進基礎設施問題。

+0

感謝您的回答!所以,我認爲檢索對象的方式是一個基礎設施問題。但是在確定哪些實體應該是AR時,這不是必需的嗎?在某些情況下,從ObjectA聚合根訪問ObjectB是合乎邏輯的,但在另一個上下文/用例中,ObjectB很可能是它自己的聚合根。那麼基礎設施問題畢竟不是一個決定因素? – 2011-06-01 18:13:49

+2

基礎設施問題不應該決定你的AR邊界。您的一致性要求應該。我們的想法是,您的域中的Concept可以是一個邊界上下文中的一個AR,另一個邊界上下文中的一個實體。直接訪問實體會破壞聚合的目的 - 這是爲了強化不變量和一致性。我建議你觀看[埃裏克埃文斯視頻](http://www.infoq.com/presentations/ddd-eric-evans),然後從DDD書中重新閱讀關於邊界上下文的章節。您的使用案例是確定BC的良好開端 – 2011-06-02 07:56:17

1

就像lulian說的,我想沒有規則說明你的AR應該是什麼樣子。如果你的AR與ObjectA,B和C屬於相同的業務上下文,那就罰款。但我認爲你也應該反思你的客戶/用例如何使用你的模型。如果你總是希望ObjectC和ObjectA和B的對象圖遍歷到C感覺是不必要的遍歷,也許你的模型是不正確的。

如果你的根對象爲對象A和你有一個ObjectARepository你可以隨時到幾個對象B添加存儲庫的方法,如GetObjectCsByObjectA(對象A對象A),將列出所有的C的一個A. 如果ObjectC可兒,上面的解決方案也許是不是最好的,因爲你得到所有的C爲一個A.

必須最重要的是你的GUI /客戶端將如何使用此AR(重複我自己...) 您可以添加擴展方法添加Linq過濾器或搜索以緩解從A到C的遍歷。不是我最喜歡的,但它的工作原理。更好的做法是嘗試在ObjectA中用Object對象包裝ObjectB的集合,或者只是一個簡單的listwrapper類,它不是持久化的,而是在訪問這個集合時創建的。此包裝可以提供適合您的GUI的必要訪問方法,以及添加,替換和刪除列表項時的驗證。包裝將成爲客戶的捷徑,所以他們不需要打擾AR如何在AR內部構建。

ObjectB和ObjectC是否與此AR之外的其他實體有任何關聯?

+0

您是對的,在閱讀回覆後,規則是完全相關的。我必須同意你的看法,確定AR是一個不僅與域邊界相結合的過程,而且也是用例。我不知道我怎麼知道我的聚合中的任何對象是否可以自己聚合而不用查看用例。爲了回答你最後的問題,是的,ObjectC確實在AR之外還有其他關聯。 – 2011-06-01 18:19:18

+1

一個共同的準則是AR內的所有Child對象都不應該有AR邊界以外的關聯。爲什麼?那麼如果你想刪除/刪除根實例,它的所有AR子對象也應該被刪除。如果孩子像你的ObjectC那樣具有外部關聯,這可能是一個棘手的操作。也許你需要將ObjectC作爲一個AR升級到自己的倉庫?子實體可以在其他AR中自己AR。 – 2011-06-01 21:33:48

+0

「父母/孩子」可能不明確。遵循Evans模型,AR *不能既是AR又是另一AR的成員。兩個AR可以有關係。外部對象只能引用AR,但AR中的實體可以保存外部引用。 ObjectA中的ObjectC列表不會賦予聚合成員資格。如果ObjectC確實是一個AR,它就是AR-AR關係。如果ObjectC確實是ObjectA AR的一部分,則ObjectC不能也是AR。僅從ObjectA引用ObjectC並不足以區分這兩種可能性。 AR是概念性的,不能單獨由代碼表示。 – Sisyphus 2011-06-02 11:14:36