1

上下文:
我有一本實體書。一本書可以有一個或多個描述。描述是值對象。如何建模值對象關係?

問題:
說明可能比其他說明更具體。例如,如果描述包含書籍的內容以及封面的外觀,那麼它的描述比僅僅討論封面外觀的描述更具體。我不知道如何對它進行建模以及如何讓存儲庫進行保存。瞭解這些關係並不是本書或圖書描述的責任。其他一些對象可以處理這個問題,然後讓存儲庫保存關係。但BookRepository.addMoreSpecificDescription(Description,MoreSpecificDescription)對於存儲庫來說似乎很難保存。

在DDD中如何處理這樣的事情?

回答

7

另外兩個答案是一個方向(+1 btw)。我進入原始問題編輯後,所以這裏是我的兩個分...

我定義一個值對象作爲一個對象與兩個或更多的屬性,可以(和)在其他實體之間共享。它們只能在一個聚合根中共享,也沒關係。只是他們可以(而且)共享的事實。

要使用您的示例,請將「描述」定義爲值對象。這告訴我,具有多個屬性的「描述」可以在幾本書籍中共享。在現實世界中,這是沒有意義的,因爲我們都知道每本書都有由撰寫或出版這本書的主人寫的獨特描述。呵呵。因此,我認爲描述並不是真正的值對象,但它們本身就是書聚合根實體boundery中的附加實體對象(在一個聚合根實體中可以有多個實體)。即使是重新發布的書籍,更新版本等,也略有不同的描述來描述這種輕微的變化。

我相信你可以回答你的問題 - 使描述實體對象,並保護它們在你的主要書本實體聚集根(例如Book.GetDescriptions()...)之後。這個答案的其餘部分解決了我如何處理存儲庫中的值對象,其他讀這篇文章...

爲了在存儲庫中存儲值對象,並檢索它們,我們開始侵入我與自己搏鬥的同一領域當我從「數據庫優先」建模方法切換到DDD方法時。我自己就這個問題討論瞭如何在數據庫中存儲一個Value對象,並在沒有Identity的情況下檢索它。直到我退後一步,意識到我在做什麼......

在域驅動設計中,您正在爲域中的值對象建模 - 而不是您的數據存儲。這是關鍵短語。這意味着你並沒有將價值對象設計成獨立的對象存儲在數據存儲中,你可以存儲它們,只要你喜歡!

我們來看一個常見的值對象DDD示例,即Address()。 DDD表示郵寄地址是完美的價值對象示例,因爲值對象的定義是誰的屬性的對象總和來創建對象的唯一性。如果一個屬性發生變化,它將是一個不同的值對象。並且相同的Value Object 9teh的屬性總和)可以在其他實體之間共享。

郵寄地址是一個位置,是地球上特定位置的長/緯度。多個人可以住在地址上,當有人移動時,現在佔用相同郵寄地址的新人使用相同的值對象。

所以,我有一個Person()對象的MailingAddress()對象中有地址信息。它通過get/update/create methods/services保護在我的Person()聚合根後面。

現在,我們如何存儲並分享給同一家庭中的人?啊,DDD就在於 - 你不是直接從你的DDD建模你的數據存儲(儘管這很好)。這就是說,您可以簡單地創建一個呈現Person對象的單個表格,並在其中包含您的郵寄地址的列。您的Repository的工作是將這些信息從數據存儲重新提供給Person()和MailingAddress()對象,並在創建/更新操作期間將其分解。

是的,你現在在你的數據存儲中有重複的數據。具有相同郵寄地址的三個Person()實體現在都具有三個Value對象數據的單獨副本 - 這沒關係!值對象意味着很容易被複制和刪除。 「複製」是DDD劇本中的最佳單詞。

所以總結一下,Domain Drive Design是關於建模您的域以表示您對象的實際業務用途。您可以單獨對Person()實體和MailingAddress值對象建模,因爲它們在應用程序中以不同方式表示。你堅持他們一個複製的數據,這是在你的Person表的同一個表中的額外的列。

以上所有內容均嚴格爲DDD。但是,DDD意味着只是「建議」,而不是遵守規則。這就是爲什麼你可以自由地做我自己和其他人做的事情,這種寬鬆的DDD風格。如果你不喜歡複製的數據,唯一的選擇就是你可以爲MailingAddress()創建一個單獨的表,並在其上添加一個標識列,並更新你的MailingAddress()對象,使其具有該標識 - 知道你只使用該標識將其鏈接到其他共享它的Person()對象(我個人喜歡第三對多關係表,以保持查詢速度)。如果可能,您將屏蔽該Idenity(即內部修飾符)暴露在聚合根/域之外,以便其他層(如應用程序或UI)不知道MailingAddress的標識列。另外,我會爲MailingAddress創建一個專用的Repository,並使用PersonService層將它們合併到正確的對象Person.MailingAddress()中。

對不起,咆哮...... :)

4

首先,我認爲評論應該是實體。

其次,你爲什麼試圖建立評論之間的關係?我沒有看到他們之間的自然關係。 「比......更具體」太模糊,不適合作爲一種關係。

如果您在建模時遇到困難,那表明可能沒有關係。

+0

注:我已經使用描述而不是審查來修改示例。我認爲這種關係並不自然。比方說,用戶喜歡看到顯示摘要的描述。然後任何描述顯示摘要(和更多)將適合。這就是我的意思是'比'更具體'。 – koen 2009-12-18 21:21:04

1

我同意傑森。我不知道您的理由是如何評估價值對象。

我希望一個書評有BookReviewContentItems,讓你可以對書評的方法調用,以決定是否有足夠具體的,該方法做出決定基於查詢的內容項目的集合。

+0

理由是它們是不可變的。書評很糟糕。書中的描述更適合這個例子。書籍描述是我不關心身份的元數據。我會更新這個例子。 – koen 2009-12-18 21:16:18