聚合Aggregate

什麼是聚合:服務器

聚合是一個更大的封裝單位,而不只僅是一個類。每一個事物的範圍限定在單個聚合內。聚合組件的使用期被界限在整個聚合的生命週期中。
具體的,一個聚合將會處理命令,請求事件,並在其中封裝一個狀態模型,使其可以實現所需的命令驗證,從而維護聚合的不變量(即業務規則)

聚合和聚合根之間有什麼區別:框架

聚合造成對象關係的樹或者圖。而聚合根是樹的「頂」,它整體上說明了聚合而且表明了剩餘部分,它很重要由於他是全部通訊的地方。

我知道聚合是事務邊界,但我真的須要在同一個事務中事務更新兩個聚合。我該怎麼辦?設計

咱們應該從新思考以下:
   ①你的聚合邊界
   ②每一個聚合的自責
   ③你怎麼樣才能夠僥倖逃脫掉在讀的一端或者在一個saga中
   ④你的領域的真實的非功能性的需求
   若是你寫了一個解決方案,可是有兩個或者多個的聚合以事務的方式耦合了,那麼就說明你沒有理解聚合

爲何使用GUID做爲ID是一個很好的作法?code

由於它們(合理)全局惟一,而且能夠由服務器或客戶端生成。

如何獲取新建立的聚合的ID?對象

這是一個重要的看法,客戶端能夠生成本身的ID。
若是客戶端生成了GUID而且將其放在建立聚合的命令中,這不是一個問題。不然,你須要從適當的讀取端進行輪詢,其中ID將以最終一致的時間框架出現。顯然,這種是比在一開始就生成的方式要
脆弱的多的

咱們應該容許聚合間的引用嗎?生命週期

從真實的「內存引用」的意義而言,固然是不能夠的
在寫方面,一個真實的從一個聚合到另一個聚合的內存引用是不對和禁止的。由於聚合的定義不容許到達他本身的外部(若是容許的話,那麼意味着聚合再也不是事務邊界,意味着我能夠再也不去
思考維護其不變量的能力,他亦阻止了聚合的分隔)
使用字符串標識符引用另外一個聚合是能夠的。在寫方面是沒有用的(由於標識符必須被視爲不透明的值,所以聚合不能到達自身以外)。讀的一端可能自由的使用這些信息來進行有趣的相關性

如何在一組聚合中驗證命令?事件

這是一種再也沒法經過聚合進行查詢了的常見的反作用,有幾個答案:
①客戶端驗證
②使用讀的一端
③使用saga
④若是那些徹底不切實際,那麼這就該考慮是不是聚合的邊界不對

如何保證總體的引用完整性?事務

你如今仍在思考外來的關係引用,而不是聚合。看最後的那個問題。固然,記住僅僅由於是兩個表的關係設計不易任何方式代表他們是兩個聚合。聚合設計是不一樣的

如何確保新建立的用戶具備惟一的用戶名?內存

這是一個常見的問題,由於咱們明確地不會在寫方面執行交叉聚合操做。可是,咱們有不少選擇:
①建立一個已經分配了用戶名字的讀取端。讓客戶端能夠交互式的以鍵入用戶名的方式查詢讀取端。
②建立一個響應式的saga來標記和停用那些不過是以用戶名的讀本建立的帳戶(不管是不是極端巧合或者惡意的或者因爲客戶的錯誤)
③若是最終的一致性不夠快,那麼能夠考慮在寫的一端添加一個小的本地讀取方面得標。確保聚合的食物插入該表

當我下訂單時,如何驗證客戶ID是否真的存在?字符串

假設客戶和訂單都彙集在這裏,很明顯,訂單的聚合是不能驗證這個的,由於這意味着到達了聚合以外了
在事實以後檢查,在一個記錄了‘broken’訂單的saga或者僅僅在一個讀取端。畢竟,訂單的最重要的事實徹底的記錄它,大概任何關於訂單的收件人的有趣的數據將會被複制到訂單聚合中
(引用到用戶去訪問其地址是壞的設計,訂單老是用來提供一個特定的地址,不管是否在將來客戶改變他們的地址)
可以使用那些被記錄在破損訂單的數據意味着你有機會來拯救它,扭轉局面---這使得比下列命令更有意義,由於違反外鍵約束!

如何使用單個命令更新一組聚合?

單一的命令是不能操做一組聚合的。
首先,問問本身你是否是真的須要一個命令更新多個聚合,是什麼狀況致使這個需求。
然而,你是能夠這麼作的。容許一種新的「批量命令」。在概念上包含你想要發佈的命令以及一組您要發佈的聚合(指定或明確指定)。寫入段不夠強大處處理這種批量操做,可是它能夠建立相應
的」批量事件」。一個saga捕獲這個事件,並在每一個指定的聚合上執行命令。當命令失敗的時候,saga能夠視狀況調用rollback或者發送一封郵件。
這種方法有一些優勢:咱們將批量操做的意圖存儲在事件存儲中。saga自動回滾或等效。
儘管如此,不得不訴諸於此解決方案,這代表您的聚合的整體邊界並不正確。你可能想考慮改變你的聚合邊界,而不是爲此創建一個saga。

什麼是分片?

一種在多個寫入端節點上分發大量聚合的方式。咱們能夠很容易地分解聚合,由於它們徹底是自立的。
咱們能夠很容易地分割聚合,由於它們沒有任何外部引用。

聚合能夠將事件發送到另外一個聚合?

不能夠
你的聚合和命令處理器這些因素表明性的早已在代碼中使這個想法沒法表達,可是有一個更深層次的哲學緣由:
    回去從新讀第一個問題「what's an aggregate?」
若是你設法規避命令處理程序,將事件推向另一個聚合,那麼你將會失去聚合的參與驗證的變化的機會。這就是爲何咱們僅僅容許聚合器上的命令處理程序驗證的命令建立事件。

我能從個人聚合中調用一個讀取端嗎??

不能夠

在CQRS系統中咱們麼發送email

在聚合以外的時間處理器,不要早命令處理程序中執行此操做,就像這個事件因爲丟掉了與其餘命令競爭而不會被持久化,因此email將會在一個虛假的前提下被髮送。
相關文章
相關標籤/搜索