2009-10-01 59 views
5

我試圖用ASP.NET MVC項目第一次實現DDD,我正在努力處理一些事情。域驅動設計:何時創建聚合根?

我有2個相關實體,公司和供應商。我最初的想法是,公司是一個聚合根,供應商是公司的價值對象。所以我有一個公司的倉庫,沒有供應商的倉庫。

但是,當我開始構建我的應用程序時,我最終需要爲供應商單獨列表,創建和更新表單。這個清單很簡單,我可以打電話給Company.Suppliers,創建很糟糕,我可以做Company.Suppliers.Add(供應商),但更新讓我頭疼。由於我只需要一個實體,並且我不能將它完全粘貼在表單之間的內存中,所以我最終需要重新提取公司和所有供應商,並找到需要綁定的實體並再次修改並堅持它回到數據庫。

我真的只需要做一個GetOne,如果我有一個供應商的存儲庫。我可以通過添加一個GetOneSupplier給我的公司或CompanyRepository添加一些解決方法,但這看起來很垃圾。

所以,我真的想知道它是否真的是一個價值對象,而不是一個完整的域實體本身。

tldr;

是否需要單獨的列表/創建/更新視圖/頁面一個實體應該是它自己的根的標誌?

回答

34

根據您的術語,我假設您正在根據Eric Evans的書執行DDD。這聽起來像是你已經確定了一個問題,你最初的模型建立在哪裏,並且你是對的。

你提到你認爲供應商作爲Value Object ......我建議它不是。 A Value Object主要是通過其屬性來識別的。例如,「2009年9月30日」的日期是價值對象。爲什麼?因爲具有不同月/日/年組合的所有日期實例都是不同的日期。具有相同月份/日期/年份組合的所有日期實例都被視爲相同。我們永遠不會爭辯,因爲它們是相同的,因此我們的「2009年9月30日」交換.-)

另一方面,Entity主要由其「ID」標識。例如,銀行賬戶有ID - 他們都有賬戶號碼。如果銀行有兩個賬戶,每個賬戶都有500美元,如果他們的賬戶號碼不同,他們也是如此。他們的財產(在這個例子中,他們的平衡)沒有識別他們或暗示平等。我敢打賭,即使他們的餘額相同,我們也會爭論在換銀行賬戶:-)

因此,在您的示例中,我會考慮供應商爲Entity,因爲我會假定每個供應商主要由其ID標識比其屬性。我自己的公司與世界上的另外兩家公司分享它的名字 - 但我們並非都是可以互換的。

我認爲你的建議是,如果你需要CRUD的對象的意見然後它是一個Entity作爲一個經驗法則可能是真實的,但你應該更關注什麼使一個對象不同於其他:屬性或ID。

現在儘可能Aggregate Root走吧,你要專注於對象的生命週期和訪問控制。考慮我有一個博客,其中有許多帖子,每篇都有很多評論 - Aggregate Root(s)在哪裏?讓我們從評論開始。沒有帖子的評論是否有意義?你會創建一個評論,然後去找一個帖子並附加到它嗎?如果你刪除了一篇文章,你會保留它的意見嗎?我建議一個帖子是一個Aggregate Root與一個「葉」 - 評論。現在考慮博客本身 - 它與帖子的關係類似於帖子和評論之間的關係。它在我看來也是一個Aggregate Root與一個「葉」 - 職位。

因此,在你的榜樣,是有公司與供應商之間的緊密關係,從而,如果你刪除公司(我知道...你可能只有公司的一個實例),您也將刪除其供應商?如果刪除「星巴克」(美國的一家咖啡公司),是否所有的咖啡豆供應商都不復存在?這一切都取決於你的域和應用程序,但我建議很可能你的EntitiesAggregate Roots,或者一個更好的方式來思考他們的是,他們均沒有「葉子」集合根不多(無聚集)。換句話說,公司不控制對供應商生命週期的訪問或控制生命週期。它只與供應商(或許多對多)有一對多的關係。

這給我們帶來Repositories。 A Repository用於存儲和檢索Aggregate Roots。你有兩個(從技術上講,他們不聚集任何東西,但比「存儲庫存儲聚集根或聚合中沒有離開的實體」更容易),因此你需要兩個Repositories。一個用於公司,另一個用於供應商。

我希望這會有所幫助。也許埃裏克埃文斯潛藏在這裏,會告訴我我偏離了他的範式。

+0

真棒回答!你幫助驗證了我的想法並解釋了更多。非常感謝! 我同意,應該共享引用供應商,如果它們存在,但目前它將是用戶輸入的數據,無法驗證2個供應商是相同的。隨着系統的發展,未來可能會發生變化,但現在就是這樣。再次感謝! – 2009-10-01 14:57:27

+0

我同意這是一個很好的解釋,比我通常在DDD郵件列表中找到的更有幫助! – 2009-10-01 15:07:59

+0

明智的答案。一票從我身上。 – 2009-10-13 06:23:36

1

對我來說這聽起來很不容易 - 供應商應該有自己的存儲庫。如果一個實體在模型中可以獨立存在的邏輯可能性,那麼它應該是一個根實體,否則你最終會在稍後重構,這是多餘的工作。

儘管預先實施了額外的實施工作,但根實體始終比值對象更靈活。隨着模型的發展,我發現隨着時間的推移,模​​型中的價值對象會變得越來越少,而保持價值對象的實體通常是那些從第一天起就可以在邏輯上限制這種方式的實體。

如果公司共享供應商,那麼以供應商爲根實體也會刪除數據冗餘,因爲您不重複每個公司的供應商定義,而是共享參考,而公司和供應商之間的關聯可以是雙向的好吧,這可能會產生更多的好處。

+0

謝謝你非常明確的答案,它也有幫助。 – 2009-10-01 14:58:58