1. 聚合根、實體、值對象的區別?對象
從標識的角度:生命週期
聚合根具備全局的惟一標識,而實體只有在聚合內部有惟一的本地標識,值對象沒有惟一標識,不存在這個值對象或那個值對象的說法;引用
從是否只讀的角度:數據
聚合根除了惟一標識外,其餘全部狀態信息都理論上可變;實體是可變的;值對象是隻讀的;ant
從生命週期的角度:模型
聚合根有獨立的生命週期,實體的生命週期從屬於其所屬的聚合,實體徹底由其所屬的聚合根負責管理維護;值對象無生命週期可言,由於只是一個值;管理
2. 聚合根、實體、值對象對象之間如何創建關聯?
聚合根到聚合根:經過ID關聯;
聚合根到其內部的實體,直接對象引用;
聚合根到值對象,直接對象引用;
實體對其餘對象的引用規則:1)能引用其所屬聚合內的聚合根、實體、值對象;2)能引用外部聚合根,但推薦以ID的方式關聯,另外也能夠關聯某個外部聚合內的實體,但必須是ID關聯,不然就出現同一個實體的引用被兩個聚合根持有,這是不容許的,一個實體的引用只能被其所屬的聚合根持有;
值對象對其餘對象的引用規則:只需確保值對象是隻讀的便可,推薦值對象的全部屬性都儘可能是值對象;
3. 如何識別聚合與聚合根?
明確含義:一個Bounded Context(界定的上下文)可能包含多個聚合,每一個聚合都有一個根實體,叫作聚合根;
識別順序:先找出哪些實體多是聚合根,再逐個分析每一個聚合根的邊界,即該聚合根應該聚合哪些實體或值對象;最後再劃分Bounded Context;
聚合邊界肯定法則:根據不變性約束規則(Invariant)。不變性規則有兩類:1)聚合邊界內必須具備哪些信息,若是沒有這些信息就不能稱爲一個有效的聚合;2)聚合內的某些對象的狀態必須知足某個業務規則;
例子分析1:訂單模型
Order(一 個訂單)必須有對應的客戶信息,不然就不能稱爲一個有效的Order;同理,Order對OrderLineItem有不變性約束,Order也必須至少有一個OrderLineItem(一條訂單明細),不然就不能稱爲一個有效的Order;另外,Order中的任何OrderLineItem的數量都不能爲0,不然認爲該OrderLineItem是無效 的,同時能夠推理出Order也多是無效的。由於若是容許一個OrderLineItem的數量爲0的話,就意味着可能會出現全部 OrderLineItem的數量都爲0,這就致使整個Order的總價爲0,這是沒有任何意義的,是不容許的,從而致使Order無效;因此,必需要求 Order中全部的OrderLineItem的數量都不能爲0;那麼如今能夠肯定的是Order必須包含一些OrderLineItem,那麼應該是通 過引用的方式仍是ID關聯的方式來表達這種包含關係呢?這就須要引出另一個問題,那就是先要分析出是OrderLineItem是不是一個獨立的聚合 根。回答了這個問題,那麼根據上面的規則就知道應該用對象引用仍是用ID關聯了。那麼OrderLineItem是不是一個獨立的聚合根呢?由於聚合根意 味着是某個聚合的根,而聚合有表明着某個上下文邊界,而一個上下文邊界又表明着某個獨立的業務場景,這個業務場景操做的惟一對象老是該上下文邊界內的聚合 根。想到這裏,咱們就能夠想一想,有沒有什麼場景是會繞開訂單直接對某個訂單明細進行操做的。也就是在這種狀況下,咱們 是以OrderLineItem爲主體,徹底是在面向OrderLineItem在作業務操做。有這種業務場景嗎?沒有,咱們對 OrderLineItem的全部的操做都是以Order爲出發點,咱們老是會面向整個Order在作業務操做,好比向Order中增長明細,修改 Order的某個明細對應的商品的購買數量,從Order中移除某個明細,等等相似操做,咱們歷來不會從OrderlineItem爲出發點去執行一些業 務操做;另外,從生命週期的角度去理解,那麼OrderLineItem離開Order沒有任何存在的意義,也就是說OrderLineItem的生命周 期是從屬於Order的。因此,咱們能夠很確信的回答,OrderLineItem是一個實體。
例子分析2:帖子與回覆的模型,作個對比,以便更好地理解。
不 變性分析:帖子和回覆之間有不變性規則嗎?彷佛咱們只知道一點是確定的,那就是帖子和回覆之間的關係,1:N的關係;除了這個以外,咱們看不到任何其餘的 不變性規則。那麼這個1:N的對象關係是一種不變性規則嗎?不是!首先,一個帖子能夠沒有任何回覆,帖子也不對它的回覆有任何規則約束,它甚至都不知道自 己有多少個回覆;再次,發表了一個回覆和帖子也沒有任何關係;其次,發表回覆對帖子沒有任何改變;從業務場景的角度去分析,咱們有發表帖子的場景,有發表 回覆的場景。當在發表回覆的時候,是以回覆爲主體的,帖子只是這個回覆裏所包含的必要信息,用於說明這個回覆是對哪一個帖子的回覆。這些都說明帖子和回覆之 間找不出任何不變性約束的規則;由於帖子和回覆都有各自獨立的業務場景的須要,因此能夠很容易理解它們都是獨立的聚合根;那也很容易知道該如何創建他們之 間的關聯了,可是咱們要儘可能減小關聯,因此只保留回覆對帖子的關聯便可;帖子沒有任何須要去保存一個回覆的ID的列表;那麼你可能會說,當我刪除一個帖子 後,回覆應該是沒有存在的意義的呀?不對,不是沒有存在的意義,而是刪除了帖子後致使了回覆對帖子的關聯信息的缺失,致使數據不一致。這是由於帖子和回覆 之間有一種必然的聯繫(1:N),回覆必定會有一個對應的帖子;可是回覆有其本身的生命週期,不該該隨着帖子的刪除而級聯刪除。這種狀況下,若是你刪除了 帖子,就致使回覆也成爲了一條無效的數據;因此,咱們絕對不容許刪除任何聚合根,由於一旦你刪除了聚合根,那就意味着與該聚合根相關的其餘任何聚合根都會 有外鍵引用缺失的問題,會致使整個領域模型數據的不一致;因此,永遠都不要刪除聚合根;