怎麼樣劃分聚合

2022-09-11 07:18:07 字數 3868 閱讀 1989

一下內容學習湯雪華的博文,包括但不限於這個**:

1.聚合根、實體、值物件的區別?

從標識的角度:

聚合根具有全域性的唯一標識,而實體只有在聚合內部有唯一的本地標識,值物件沒有唯一標識,不存在這個值物件或那個值物件的說法;

從是否唯讀的角度:

聚合**了唯一標識外,其他所有狀態資訊都理論上可變;實體是可變的;值物件是唯讀的;

從生命週期的角度:

聚合根有獨立的生命週期,實體的生命週期從屬於其所屬的聚合,實體完全由其所屬的聚合根負責管理維護;實體有狀態(用值物件來描述狀態),值物件無生命週期可言,因為只是乙個值;

2.聚合根、實體、值物件三個物件之間如何建立關聯?

聚合根的引用規則:

1)聚合根到聚合根:通過id關聯;

2)聚合根到其內部的實體,直接物件引用;

3)聚合根到值物件,直接物件引用;

實體對其他物件的引用規則:

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),回覆一定會有乙個對應的帖子;但是回覆有其自己的生命週期,不應該隨著帖子的刪除而級聯刪除。這種情況下,如果你刪除了 帖子,就導致回覆也成為了一條無效的資料;所以,我們絕對不允許刪除任何聚合根,因為一旦你刪除了聚合根,那就意味著與該聚合根相關的其他任何聚合根都會 有外來鍵引用缺失的問題,會導致整個領域模型資料的不一致;所以,永遠都不要刪除聚合根;

總結一下 :

正向劃分:

1. 找最小的業務場景

2.找出聚合根(先確定可能是聚合根的實體,可能包含的實體),確定的原則是:具有獨立的生命週期(生命開始和結束)

3.確定聚合根的邊界,如包括 entity1,e2,e3.。。。這些實體要依賴於聚合根的存在而存在。聚合邊界確定法則:根據不變性約束規則(invariant)。

不變性規則有兩類:1)聚合邊界內必須具有哪些資訊,如果沒有這些資訊就不能稱為乙個有效的聚合;

2)聚合內的某些物件的狀態必須滿足某個業務規則

反向驗證:

1.驗證乙個實體是否屬於這個聚合:他還可以屬於其他聚合嗎 ?離開了這個聚合根是不是就失去了意義。

2.實體變化了,影響聚合根的內容了嗎?

再次驗證:

1.是否「同生死,共存亡」;

聚合除了封裝我們關心的資訊外最主要的目的就是為了封裝業務規則,保證資料的一致性,

業務規則比如乙個銀行賬號的餘額不能小於0,訂單中的訂單明細的個數不能為0,訂單中不能出現兩個明細對應的商品id相同,訂單明細中的商品資訊必須合法,商品的名稱不能為空,回覆被建立時必須要傳入被回覆的帖子(因為沒有帖子的回覆不是乙個合法的回覆)等

聚合應當設計的盡可能小  

聚合包含的東西過多,導致多人操作時併發衝突嚴重,導致系統可用性變差;所以實現了既能解決併發衝突的問題,也能保證讓聚合來封裝業務規則,實現模型級別的資料一致性;另外,聚合設計的小還有乙個好處,就是:業務決定聚合,業務改變聚合。聚合設計的小除了可以降低併發衝突的可能性之外,同樣減少了業務改變的時候,聚合的拆分個數,降低了聚合大幅重構(拆分)的可能性,從而能讓我們的領域模型更能適應業務的變化。

聚合之間通過id關聯

其實聚合之間無需通過物件引用的方式來關聯; 

需要關聯時,必須要  1)盡量避免多對多的關係;2)如果必須多對多,應該轉換為兩個一對多,然後都只要在雙方物件中儲存對方的id即可;

另外一篇博文

立方網怎麼樣

立方網號稱自己是中國第一家lbs 也有傳言facebook的時間軸就是抄襲的立方網。照理說,這樣的公司應該朝氣蓬勃 勇於創新的企業。但是就在最近,白雲黃鶴一名學子爆出在立方網的種種不爽,不管真實性怎麼樣,對即將找工作的同學也是一種參考,文章如下 11年畢業,畢業後去了廣州的一家國企裡面,待了大半年的...

怎麼樣定義常量

一 怎麼定義常量?1.自定義常量 必須用函式define 定義 定義完後其值不能再改變了 使用時直接用常量名,不能像變數一樣在前面加 s 2 系統常量 file php程式檔名 line php程式檔案行數 php version 當前解析器的版本號 php os 執行當前php版本的作業系統名稱 ...

Geotrust SSL證書怎麼樣

geotrust ssl證書主要有4種,其中 2種為只驗證網域名稱所有權而不驗證營業執照的快速dv ssl證書 quickssl premium 入門型rapidssl 只有一款需要驗證營業執照的證書ov ssl證書 true business id 還有一款就是新推出的ev ssl證書 true ...