- 中臺落地手記:業務服務化與數據資產化
- 張亮
- 1745字
- 2021-09-08 16:35:23
2.2.1 領域驅動建模介紹
傳統的模型設計方法有以下幾種。
拖曳式設計,例如Smart UI模式,把展示層、業務處理層、數據處理層等過程簡單封裝成固定可拖曳模塊,用戶只需要進行簡單的排列組合即可完成系統建模以及業務邏輯開發。
業務過程式設計,例如Transaction Script模式,這種模式嚴格按每個業務流程走向來設計程序,這種面向過程的設計現在還在大量使用。
領域驅動設計(Domain-Driven-Design, DDD),這種方法按照領域邊界來設計建模。DDD的概念其實早就出現了,相關的理論也發展多年,只是近年隨著微服務的興起而再次受到重視,重新活躍起來。
前兩種建模方法在面對簡單的、少租戶的業務建模方面是非常方便快捷的,輕量而又高效率,但是面對復雜交叉業務,多租戶、高并發、大數據量的系統就會顯得單薄,就算勉強支撐起應用,后期維護也將非常耗時耗力。
從微服務的發展歷程及設計思想來看,業務的微邊界設定、服務化的拆分與DDD的限界上下文、聚合等建模思路是一致的,因此本書推薦DDD這種業務視角的設計方法。
DDD建模典型步驟如圖2-4所示。
1)事件風暴完成所有事件流程分析。
2)找出事件流程中的實體與值對象。

圖2-4 DDD建模典型步驟
3)將實體與值對象組合成一個完整的聚合。
4)確認聚合的聚合根。
5)確認聚合與限界上下文的對應關系。
6)根據限界上下文劃分微服務。
我們先梳理一下本書涉及的一些概念,后面結合落地情況進一步解釋。
1.業務描述方面涉及的概念
(1)實體
參與業務流程的各主體單元,常常結合核心場景分析、產品生命周期、用戶旅程等輔以事件風暴來抽取,例如購票業務中參與的實體有客戶、代理、訂單、機票、航空公司等。
(2)領域
業務流程中實體與實體之間的關系網,例如客戶實體和訂單實體是1:n的關系,兩者所構成的關系還會包含其他實體及它們之間的關系,這個巨大的關系網組成了一個領域,例如銷售域等。領域還可以劃分為核心域、支撐域和通用域等子域,例如銷售域可進一步劃分為購買域、出售域、價格域等。
2.DDD解決方案方面對應的概念
(1)限界上下文
在領域中圍繞某一個實體,以其為中心,再加上其描述信息、功能信息和由一定的外界聯系信息組成的上下文相關環境信息等一起組成了這個實體的限界上下文。例如客戶實體,包含其自身的屬性描述、功能標簽,與地址實體這個外界聯系等共同組成了“客戶”這個限界上下文。當然,這里面要注意的是,上述領域中的子域與限界上下文不一定是一一對應的關系。
(2)聚合與聚合根
限界上下文中的實體之間可能存在強相關的關系,例如訂單和訂單項,那么訂單和訂單項就組成了一個聚合,而這個聚合的唯一標識符,或者說是外界溝通的“聯絡人”——訂單就是這個聚合的聚合根。聚合作為限界上下文的組成單位,同時會作為存儲入庫的基本單位。
(3)值對象
首先,值對象也是實體,這一類實體在某個限界上下文中有特定的實例,不需要唯一標識符。當更改值之后會變成另外一個新的對象,例如訂單中的地址信息、商品的顏色信息等。
但是,值對象在另外一個限界上下文中可以是聚合根,例如,商品在限界上下文中是值對象,但是商品在商品限界上下文中是作為聚合根存在的,即值對象與聚合根的身份在不同的限界上下文中是變化的,這點要理解清楚。
DDD不只是對業務邏輯進行抽象建模,也可以對后續的微服務拆分、數據庫設計、RESTful API設計提供指導,具體如下所示。
(1)以限界上下文粒度進行微服務拆分
限界上下文是由聚合構成的,限界上下文中的聚合有比較緊密的依賴關系,如果在聚合的粒度上劃分微服務,則微服務之間的耦合性過高、內聚性不夠。例如在商品限界上下文中把規格與顏色等聚合設計成微服務顯然是設計過度的體現。
(2)以聚合粒度進行數據庫設計
DDD中的聚合是最小粒度的業務單元,其具有完整的業務描述,而且關鍵是每個聚合都有一個聚合根,這和數據庫范式設計中的唯一標識符不謀而合,所以一個聚合至少可以對應一張表。
(3)RESTful API設計
REST以資源為中心,這些資源通過URI來確定,我們使用HTTP中的動詞+資源名稱來使用REST。而DDD中強調的是先弄清楚資源的處理邏輯,再在虛擬世界中建模,對實體資源的處理顯然要比HTTP的CRUD動詞要復雜得多。那這兩者的理念如何結合呢?答案就是在HTTP動詞+資源名稱組成的URI后面還需要加入業務動作,例如PUT/account/close、PUT/account/reopen。對賬戶的更新所包含的業務操作不再局限到函數中執行,而是直接在API上體現業務,這大大提升了設計的友好性及程序的可讀性。