UML:
聚合關係:成員物件是整體的一部分,但是成員物件可以脫離整體物件獨立存在。
如汽車(Car)與引擎(Engine)、輪胎(Wheel)、車燈(Light)之間的關係為聚合關係,引擎、輪胎、車燈可以脫離車而存在,比如把一個引擎換到另一個汽車上也可以。
組合關係:也表示的是一種整體和部分的關係,但是在組合關係中整體物件可以控製成員物件的生命週期,一旦整體物件不存在,成員物件也不存在,整體物件和成員物件之間具有同生共死的關係。
所以,聚合和組合的差別就一點:整體和部分的生命週期是否一致,即整體消亡後,成員物件是否可以脫離整體物件而單獨存在。
DDD聚合關係:
也是一種整體和部分的關係,部分脫離整體會變得毫無意義,強調同生共死的一致的生命週期。所以,從定義來看DDD中的聚合應該和UML中的組合關係是一致的。
按照上面的定義,我們在來分析一下一個典型的例子,就是公司和部門的關係。
UML的角度:
1、一個公司由多個部門組成,所以滿足整體和部分的關係;
2、一個部門不能脫離公司和加入到其他公司;
所以,在UML中應該屬於組合關係,沒有問題。
DDD的角度:
雖然基於UML的角度,公司和部門屬於組合關係,那在DDD中是否應該把部門聚合在公司下麵呢?我的看法是,雖然從生命週期上,確實部門不能脫離公司。
但是DDD的聚合設計要考慮的因素會更加豐滿,比如:
- DDD強調需求和Bounded Context,也就是會基於需求和背景關係進行建模,我們建模前必須要先確定當前的需求和背景關係是什麼;
- 整體在當前背景關係是否強關心部分的存在;
- 整體和部分之間是否存在某些不變性規則;
- 操作整體與操作部分的業務場景是否一致;
- 效能問題,如果整體聚合的部分數量過大,那也不會考慮聚合,即小聚合原則;
- 一致性問題,我們在設計系統時,即便把本該是聚合在一起的物件分開設計為多個聚合,也可以從技術上去解決一致性,比如透過領域服務來完成多個聚合的協同建立、刪除、修改,並能透過資料庫事務來保證嚴格的強一致性;
- DDD領域建模會對領域概念進行抽象,所以再領域模型中,也許就沒有公司了,而是隻有部門,把公司也看成是一個頂層的部門就行,所以自然就不會有公司這個聚合根了;
所以,在進行DDD聚合設計時,如果僅從整體刪除後部分會變得毫無意義(即物件之間的生命週期)這個點去推導的話,那考慮的就太單薄了,很有可能會得出不合理的聚合設計。
這是沒有認真分析業務需求,沒有分析業務規則不變性,沒有對領域概念進行合理抽象,沒有進行OO軟體設計原則的應用的表現。
我想,這也是為什麼DDD聚合設計為何會如此之難的原因了。
所以,結論是,以上案例由於需求不明,無法進行聚合設計,大家是不是很意外呢?居然沒有給出答案:)
原文地址:https://www.cnblogs.com/netfocus/p/11078464.html
.NET社群新聞,深度好文,歡迎訪問公眾號文章彙總 http://www.csharpkit.com
朋友會在“發現-看一看”看到你“在看”的內容