聚合(根)、实体、值对象精炼思考总结
1.??????聚合根、實體、值對象的區(qū)別?
從標識的角度:
聚合根具有全局的唯一標識,而實體只有在聚合內(nèi)部有唯一的本地標識,值對象沒有唯一標識,不存在這個值對象或那個值對象的說法;
從是否只讀的角度:
聚合根除了唯一標識外,其他所有狀態(tài)信息都理論上可變;實體是可變的;值對象是只讀的;
從生命周期的角度:
聚合根有獨立的生命周期,實體的生命周期從屬于其所屬的聚合,實體完全由其所屬的聚合根負責管理維護;值對象無生命周期可言,因為只是一個值;
2.??????聚合根、實體、值對象對象之間如何建立關(guān)聯(lián)?
聚合根到聚合根:通過ID關(guān)聯(lián);
聚合根到其內(nèi)部的實體,直接對象引用;
聚合根到值對象,直接對象引用;
實體對其他對象的引用規(guī)則:1)能引用其所屬聚合內(nèi)的聚合根、實體、值對象;2)能引用外部聚合根,但推薦以ID的方式關(guān)聯(lián),另外也可以關(guān)聯(lián)某個外部聚合內(nèi)的實體,但必須是ID關(guān)聯(lián),否則就出現(xiàn)同一個實體的引用被兩個聚合根持有,這是不允許的,一個實體的引用只能被其所屬的聚合根持有;
值對象對其他對象的引用規(guī)則:只需確保值對象是只讀的即可,推薦值對象的所有屬性都盡量是值對象;
3.??????如何識別聚合與聚合根?
明確含義:一個Bounded Context(界定的上下文)可能包含多個聚合,每個聚合都有一個根實體,叫做聚合根;
識別順序:先找出哪些實體可能是聚合根,再逐個分析每個聚合根的邊界,即該聚合根應(yīng)該聚合哪些實體或值對象;最后再劃分Bounded Context;
聚合邊界確定法則:根據(jù)不變性約束規(guī)則(Invariant)。不變性規(guī)則有兩類:1)聚合邊界內(nèi)必須具有哪些信息,如果沒有這些信息就不能稱為一個有效的聚合;2)聚合內(nèi)的某些對象的狀態(tài)必須滿足某個業(yè)務(wù)規(guī)則;
例子分析1:訂單模型
Order(一?個訂單)必須有對應(yīng)的客戶信息,否則就不能稱為一個有效的Order;同理,Order對OrderLineItem有不變性約束,Order也必須至少有一個OrderLineItem(一條訂單明細),否則就不能稱為一個有效的Order;另外,Order中的任何OrderLineItem的數(shù)量都不能為0,否則認為該OrderLineItem是無效?的,同時可以推理出Order也可能是無效的。因為如果允許一個OrderLineItem的數(shù)量為0的話,就意味著可能會出現(xiàn)所有?OrderLineItem的數(shù)量都為0,這就導(dǎo)致整個Order的總價為0,這是沒有任何意義的,是不允許的,從而導(dǎo)致Order無效;所以,必須要求?Order中所有的OrderLineItem的數(shù)量都不能為0;那么現(xiàn)在可以確定的是Order必須包含一些OrderLineItem,那么應(yīng)該是通?過引用的方式還是ID關(guān)聯(lián)的方式來表達這種包含關(guān)系呢?這就需要引出另外一個問題,那就是先要分析出是OrderLineItem是否是一個獨立的聚合?根。回答了這個問題,那么根據(jù)上面的規(guī)則就知道應(yīng)該用對象引用還是用ID關(guān)聯(lián)了。那么OrderLineItem是否是一個獨立的聚合根呢?因為聚合根意?味著是某個聚合的根,而聚合有代表著某個上下文邊界,而一個上下文邊界又代表著某個獨立的業(yè)務(wù)場景,這個業(yè)務(wù)場景操作的唯一對象總是該上下文邊界內(nèi)的聚合?根。想到這里,我們就可以想想,有沒有什么場景是會繞開訂單直接對某個訂單明細進行操作的。也就是在這種情況下,我們?是以O(shè)rderLineItem為主體,完全是在面向OrderLineItem在做業(yè)務(wù)操作。有這種業(yè)務(wù)場景嗎?沒有,我們對?OrderLineItem的所有的操作都是以O(shè)rder為出發(fā)點,我們總是會面向整個Order在做業(yè)務(wù)操作,比如向Order中增加明細,修改?Order的某個明細對應(yīng)的商品的購買數(shù)量,從Order中移除某個明細,等等類似操作,我們從來不會從OrderlineItem為出發(fā)點去執(zhí)行一些業(yè)?務(wù)操作;另外,從生命周期的角度去理解,那么OrderLineItem離開Order沒有任何存在的意義,也就是說OrderLineItem的生命周?期是從屬于Order的。所以,我們可以很確信的回答,OrderLineItem是一個實體。
例子分析2:帖子與回復(fù)的模型,做個對比,以便更好地理解。
不?變性分析:帖子和回復(fù)之間有不變性規(guī)則嗎?似乎我們只知道一點是肯定的,那就是帖子和回復(fù)之間的關(guān)系,1:N的關(guān)系;除了這個之外,我們看不到任何其他的?不變性規(guī)則。那么這個1:N的對象關(guān)系是一種不變性規(guī)則嗎?不是!首先,一個帖子可以沒有任何回復(fù),帖子也不對它的回復(fù)有任何規(guī)則約束,它甚至都不知道自?己有多少個回復(fù);再次,發(fā)表了一個回復(fù)和帖子也沒有任何關(guān)系;其次,發(fā)表回復(fù)對帖子沒有任何改變;從業(yè)務(wù)場景的角度去分析,我們有發(fā)表帖子的場景,有發(fā)表?回復(fù)的場景。當在發(fā)表回復(fù)的時候,是以回復(fù)為主體的,帖子只是這個回復(fù)里所包含的必要信息,用于說明這個回復(fù)是對哪個帖子的回復(fù)。這些都說明帖子和回復(fù)之?間找不出任何不變性約束的規(guī)則;因為帖子和回復(fù)都有各自獨立的業(yè)務(wù)場景的需要,所以可以很容易理解它們都是獨立的聚合根;那也很容易知道該如何建立他們之?間的關(guān)聯(lián)了,但是我們要盡量減少關(guān)聯(lián),所以只保留回復(fù)對帖子的關(guān)聯(lián)即可;帖子沒有任何必要去保存一個回復(fù)的ID的列表;那么你可能會說,當我刪除一個帖子?后,回復(fù)應(yīng)該是沒有存在的意義的呀?不對,不是沒有存在的意義,而是刪除了帖子后導(dǎo)致了回復(fù)對帖子的關(guān)聯(lián)信息的缺失,導(dǎo)致數(shù)據(jù)不一致。這是因為帖子和回復(fù)?之間有一種必然的聯(lián)系(1:N),回復(fù)一定會有一個對應(yīng)的帖子;但是回復(fù)有其自己的生命周期,不應(yīng)該隨著帖子的刪除而級聯(lián)刪除。這種情況下,如果你刪除了?帖子,就導(dǎo)致回復(fù)也成為了一條無效的數(shù)據(jù);所以,我們絕對不允許刪除任何聚合根,因為一旦你刪除了聚合根,那就意味著與該聚合根相關(guān)的其他任何聚合根都會?有外鍵引用缺失的問題,會導(dǎo)致整個領(lǐng)域模型數(shù)據(jù)的不一致;所以,永遠都不要刪除聚合根;
總結(jié)
以上是生活随笔為你收集整理的聚合(根)、实体、值对象精炼思考总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 过年家里摆供都买和摆什么水果
- 下一篇: 领域驱动设计之聚合与聚合根实例一