2017-03-06 93 views
1

聚合根的成員實體指向根實體(不是相反方向)可以嗎?指向根實體的DDD /聚集根/成員實體

假設我有人口AR(其中人口是根實體,人口會員是成員實體之一)。

我正在評估人口與人口會員之間的關聯方向。在另一端還有另一個實體,人(自己的AR,人口會員有人蔘照)。

在ER(數據庫)世界中,我們通常會從人口會員朝向人口(人口成員是人口與人之間的多對多關係中的關聯表)進行關聯。

但是我認爲在DDD世界中,我應該打破這種習慣,並且使聯想從人口(在概念模型中)指向人口成員。

無論如何,在此之前,我想確認是否(在其他一些情況下)我們被允許從成員實體向根實體關聯。

有什麼想法?

+1

也許這是以某種方式與我的問題相關:http://stackoverflow.com/questions/9804815/associations-traversal-direction 有了這個亮點:「當實體A和實體B之間存在關聯時,經常會發現自己只使用AB而不會使用BA這可能是因爲A是一個聚合根,並且始終是您的起點,因爲無論您在何處操作B等,您都已經有了對它的引用。 它表明(至少)當實體與根實體直接關聯時,方向總是來自根實體。對? –

+0

[Associations'遍歷方向]的可能的重複(http://stackoverflow.com/questions/9804815/associations-traversal-direction) – guillaume31

回答

1

好吧,讓我們這個問題分成兩個部分:

  1. 是否確定爲成員單位召開參考它的總根源?
  2. 一般性綜合建模規則

讓我們從1開始:

沒有,一般子實體不應抱參考總根源。聚合根是整個聚合的入口點,並且必須保持其一致性邊界。這意味着,聚合的每個改變都必須通過根實體轉發(通過調用根實體的方法在oop中)。聚集根可以返回對子實體的引用,但它們必須是暫時的。此外,客戶端不應對聚合根外的子實體執行更改 - 否則可能違反一致性。考慮到這一點,我並沒有真正看到子實體持有對其根目錄的引用的理由(從客戶的角度來看 - 您已經有權訪問根目錄,是嗎?)。我現在看到的唯一例外是當你需要將模型翻譯成某些特定的需求時(例如表示層需要根實體ID來產生有意義的JSON輸出)。但是,即使在這種情況下,您可能會創建一個單獨的讀取模型或提供專門的彙編器來構建所需的DTO。

好了,現在到了第二點:

似乎您試圖你會建立自己的數據庫模型以同樣的方式進行建模域的實體。在DDD中,我們應該首先關注業務需求和我們模型的行爲。建立一個有意義的領域模型時,數據關係並不那麼重要(稍後我們會對其進行細化)。因此,首先您應該專注於從您的領域專家那裏收集業務案例場景。總量應該建立在真正的業務不變量上。您應該與您的團隊(包括業務成員)一起創建一個通用模型。經過多次知識討論後,您的設計很可能會看起來完全不同。也許Person並不是一個真正的聚合根,而只是一個價值對象?也許你甚至不需要PopulationMembership實體?聚合最常見的設計是具有多個值對象的單個(根)實體。除此之外 - 我經常創建完全獨立的數據庫模型,幾乎沒有連接(id除外)到域模型。我使用翻譯層(映射器組件)在域< - > dbmodel之間進行轉換。在我最近的項目中,我的db模型與領域層極爲不同(它專門針對持久層的需求進行了調整 - 例如,使用了很多平面屬性 - 不是完整對象,而是簡單原始值)。在關係數據庫的情況下,你甚至可以明確地提供雙向關係(實際上,你甚至不需要使用任何orm)。將db模型與領域模型分離有很多優點。設計絕對更柔軟。但是,db < - >域圖層之間的映射成本(開發人員工作)對於簡單項目來說可能太大。在這種情況下,我通常從公共模型開始,然後重構爲可分層。

哦,另一件重要的事情 - 通常只是通過id來引用其他聚合根目錄是個好主意。這樣,您就沒有複雜對象圖的問題,並且您不必擔心在單個事務中修改其他聚合(聚合根不應該修改其他根)。如果您需要在聚合之間進行通信 - 請改用事件。

請參閱由沃恩弗農偉大的系列文章:

http://dddcommunity.org/library/vernon_2011/

我認爲這些文章可以幫助您瞭解集結建模的概念。

+0

我想補充說,爲了從數據庫模型中拆分領域模型(如您所命名的它)你可以使用CQRS,其中有兩個分離的模型:寫模型(又名Aggregates)和讀模型(UI/Presentation可以看到什麼)。如果您選擇CQRS,那麼這種分離非常自然且清晰。 –

+0

@ConstantinGALBENU感謝您的評論。是的,爲寫和讀創建單獨的模型是一個好主意。這些模型甚至可以使用不同的數據庫,根據不同層次的具體需求進行調整。但是,在我的答案中,我使用「數據庫模型」術語來描述直接從數據庫映射的純數據(無邏輯)類。根據我們使用的技術,我們的域類可以與我們的數據庫映射類幾乎相同或者完全不同(例如,域類使用複雜對象與數據庫映射類中的平面原語)。 –