DDD中聚合劃分的思考

在以前的《基於領域分析設計的架構規範-領域分析基礎》一文中,我有介紹過關於聚合的概念,其中聚合中非根實體的判別,是依照其不能離開聚合根而單獨存在,好比訂單明細不能離開訂單而存在,因此訂單明細只屬於訂單聚合中的一個非根實體。java

但我一直以爲還過於抽象,應該還有更嚴謹完善的判斷方式。 因此,本文就一塊兒來思考個案例:架構

案例背景

在一個資訊平臺上,用戶能登錄後發表文章,並閱讀文章。因此,在一開始,二者的關係是這樣的: 資訊平臺關係圖1.net

以後,來了一個新需求,說用戶可以對文章發表評論,那麼,評論這個實體,該如何設置呢?咱們不妨思考一下:設計

  • 評論必然是歸屬給一個文章的,至少目前需求來看是這樣,因此評論離不開文章
  • 評論必然也是一個用戶發起的,評論也離不開用戶
  • 看起來有點棘手...不過總之評論確定不能獨立存在了。

若是按我以前文章中提到的,頗有可能就會陷入上面的思考了,頗有可能會認爲評論應該是「文章的評論」,因此評論應該是隸屬於文章聚合的。日誌

設計分析

但怎麼看都以爲彆扭啊!很是彆扭!但按以前的規則來講,應該是這麼回事呀,問題出在哪呢?code

咱們來思考:評論是如何建立的?產品流程以下:blog

用戶在文章下方的評論框中輸入評論,點擊提交生命週期

那麼代碼上順利成章應該就是這樣:get

Comment comment = commentFactory.create(newCommentRequest);

但若是要強行用文章聚合的設計方案,就會很是彆扭了:產品

//既然聚合根是文章,那麼確定要先找到文章,再給文章加入評論
   Blog blog = blogRepository.getById(newCommentRequest.getBlogId());
   blog.addComment(newCommentRequest);

固然,「彆扭」一詞還不夠嚴謹,換用一個更嚴謹的說法:

評論雖然與文章有關,但其建立過程並非發生在文章的各項生命週期的操做中的,而是獨立建立的,因此,它應該是一個新的獨立的聚合

具體說來:文章有建立,編輯,審覈,刪除等等操做流程,但這個過程當中,並不會產生評論,意味着,評論並非文章生命週期中的直接衍生物,它雖然關聯了文章,也關聯了用戶,但倒是獨立被建立,也有本身獨立的生命週期(能被單獨修改,單獨刪除)。

因此,關係圖應該是

資訊平臺關係圖2

而相比之下,咱們再看更常見的非根實體,好比用戶登錄日誌訂單變動日誌,這些實體,其建立的過程,都是在用戶登錄,訂單各項操做的過程當中被建立出來的,生命週期的一開始就和根實體強綁定。

因此,此次,我總結了如下幾個原則,來判斷一個實體,是否應該做爲一個新的領域聚合的根存在,判斷的優先程度由高到低是:

  1. 該實體的建立過程是不是徹底獨立的,而非依賴與其餘某個實體的命令操做;
  2. 該實體是否能被單獨進行刪/該操做,而非好比伴隨其餘某個實體的命令操做而變更;
  3. 該實體是否有單獨的列表視圖,而非必須依賴其餘某個實體的視圖做爲前置條件(好比訂單日誌必需要先找到訂單);

其中,(2)(3)只是做爲一個輔助參考,最關鍵的仍是(1),若是(1)能遵照了,十之八九能夠定義爲一個獨立的聚合了。

相關文章
相關標籤/搜索