1. 聚合根、實體、值對象的差別?
從辨別的角度:
聚合根具有全局的唯一辨別,而實體隻有在聚合内部有唯一的本地辨別,值對象沒有唯一辨別,不存在這個值對象或那個值對象的說法;
從是否隻讀的角度:
聚合根除了唯一辨別外,其他所有狀态資訊都理論上可變;實體是可變的;值對象是隻讀的;
從生命周期的角度:
聚合根有獨立的生命周期,實體的生命周期從屬于其所屬的聚合,實體完全由其所屬的聚合根負責管理維護;值對象無生命周期可言,因為隻是一個值;
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),回複一定會有一個對應的文章;但是回複有其自己的生命周期,不應該随着文章的删除而級聯删除。這種情況下,如果你删除了 文章,就導緻回複也成為了一條無效的資料;是以,我們絕對不允許删除任何聚合根,因為一旦你删除了聚合根,那就意味着與該聚合根相關的其他任何聚合根都會 有外鍵引用缺失的問題,會導緻整個領域模型資料的不一緻;是以,永遠都不要删除聚合根;