在以前的《基於領域分析設計的架構規範-領域分析基礎》一文中,我有介紹過關於聚合的概念,其中聚合中非根實體的判別,是依照其不能離開聚合根而單獨存在,好比訂單明細不能離開訂單而存在,因此訂單明細只屬於訂單聚合中的一個非根實體。java
但我一直以爲還過於抽象,應該還有更嚴謹完善的判斷方式。 因此,本文就一塊兒來思考個案例:架構
在一個資訊平臺上,用戶能登錄後發表文章,並閱讀文章。因此,在一開始,二者的關係是這樣的: .net
以後,來了一個新需求,說用戶可以對文章發表評論,那麼,評論這個實體,該如何設置呢?咱們不妨思考一下:設計
若是按我以前文章中提到的,頗有可能就會陷入上面的思考了,頗有可能會認爲評論應該是「文章的評論」,因此評論應該是隸屬於文章聚合的。日誌
但怎麼看都以爲彆扭啊!很是彆扭!但按以前的規則來講,應該是這麼回事呀,問題出在哪呢?code
咱們來思考:評論是如何建立的?產品流程以下:blog
用戶在文章下方的評論框中輸入評論,點擊提交生命週期
那麼代碼上順利成章應該就是這樣:get
Comment comment = commentFactory.create(newCommentRequest);
但若是要強行用文章聚合的設計方案,就會很是彆扭了:產品
//既然聚合根是文章,那麼確定要先找到文章,再給文章加入評論 Blog blog = blogRepository.getById(newCommentRequest.getBlogId()); blog.addComment(newCommentRequest);
固然,「彆扭」一詞還不夠嚴謹,換用一個更嚴謹的說法:
評論雖然與文章有關,但其建立過程並非發生在文章的各項生命週期的操做中的,而是獨立建立的,因此,它應該是一個新的獨立的聚合
具體說來:文章有建立,編輯,審覈,刪除等等操做流程,但這個過程當中,並不會產生評論,意味着,評論並非文章生命週期中的直接衍生物,它雖然關聯了文章,也關聯了用戶,但倒是獨立被建立,也有本身獨立的生命週期(能被單獨修改,單獨刪除)。
因此,關係圖應該是
而相比之下,咱們再看更常見的非根實體,好比用戶登錄日誌,訂單變動日誌,這些實體,其建立的過程,都是在用戶登錄,訂單各項操做的過程當中被建立出來的,生命週期的一開始就和根實體強綁定。
因此,此次,我總結了如下幾個原則,來判斷一個實體,是否應該做爲一個新的領域聚合的根存在,判斷的優先程度由高到低是:
其中,(2)(3)只是做爲一個輔助參考,最關鍵的仍是(1),若是(1)能遵照了,十之八九能夠定義爲一個獨立的聚合了。