領域驅動設計詳解:是什麼、爲什麼、怎麼做?

雲棲號資訊:【點擊查看更多行業資訊
在這裏您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

image

阿里妹導讀:什麼是領域驅動設計?傳統分層架構在實際開發中存在哪些問題?業務開發人員如何設計並搭建自己的領域模型?阿里文娛技術專家戰獒將爲大家一一解答,並分享文娛在領域驅動設計上的實踐。

一 什麼是領域驅動設計

領域驅動設計的概念是2004年Evic Evans在他的著作《Domain-Driven Design : Tackling Complexity in the Heart of Software》(中文譯名:領域驅動設計:軟件核心複雜性應對之道)中提出的,從領域驅動設計提出距今已經有15年的時間,爲什麼最近纔開始在中國的互聯網圈大行其道?似乎一夜之間大家都在談論,那麼領域驅動設計到底幫我們解決了什麼問題?帶着這些疑問,一起來看下阿里巴巴文娛是如何實踐領域驅動設計的。

二 領域驅動設計大行其道的必然原因

軟件系統從來都不是憑空而來,而是以軟件的形式解決特定的問題。當我們面臨現實世界的複雜問題時,如何以軟件的形式落地?領域驅動設計是一套方法論,指導我們將複雜問題進行拆分、拆分出各個子系統間的關聯以及是如何運轉的,幫助我們解決大型的複雜系統在落地中遇到的問題。

Evic Evans在著作中將軟件系統的設計分爲2個部分:戰略設計和戰術設計。在戰略設計層面提出了域、子域、限界上下文等重要概念;在戰術設計層面提出了實體、值對象、領域服務、領域事件、聚合、工廠、資源庫等重要概念。如圖1所示:

image

圖1 戰略設計與戰術設計

戰略設計部分指導我們如何拆分一個複雜的系統,戰術部分指導我們對於拆分出來的單個子系統如何進行落地,在落地過程中應該遵循哪些原則。

以大家熟知的電子商務系統舉例,早期的電商系統因爲業務相對簡單,用戶量和團隊規模也較小,一個單體應用就可以搞定,隨着容量上升可以將單體應用進行橫向擴容,比如早期的淘寶就是這樣做的。拆分過程中我們可以把電商系統這個單體應用拆分成訂單子系統、庫存子系統、物流子系統、搜索推薦子系統等等,如圖2所示:

image

圖2 電商系統微服務劃分

領域驅動設計在戰略層面上的域、子域、限界上下文的劃分思想和微服務的劃分不謀而合。域對應一個問題空間,也就是上例中的電商系統;子域是把域這個大的問題空間拆分成若干個小的更容易解決的問題空間,也就是單體應用向微服務演進過程中劃分出來的各個子系統;限界上下文是解決方案空間,每個子域對應一個或多個解決方案空間。微服務的劃分是也是將一個大的問題拆分成若干個小的問題,每一個小的問題用一個或多個微服務來解決。

對於大多數開發同學來說都沒有機會接觸系統的劃分,這些工作一般是公司的技術領導層與架構師來做的,普通的開發同學日常工作中接觸到的只是某一個具體微服務或微服務中某一個模塊的落地,那是不是說領域驅動設計對於普通開發同學來說就沒有用了?當然不是這樣,領域驅動設計中的戰術設計部分就是指導我們如何落地一個系統纔可以使系統具備高可擴展性、高可讀性。

所有的系統最終都要以代碼的形式落地,而落地的工作都是由普通的開發同學來做的,系統是否具備高可擴展性、高可讀性直接影響了整個團隊的效率。

三 傳統分層架構存在的問題

對於大多數開發同學來說,大部分時間都花在落地一個個微服務上,下面我們來看阿里文娛是如何結合領域驅動設計的思想將微服務進行戰術落地的。

目前筆者接觸過的微服務大多數都是分層架構並且在Service層與Manager層實現具體的業務邏輯,使用DO、DTO、BO、VO等進行數據傳輸,數據和行爲基本完全隔離。這種分層結構圖3是《Java開發手冊》中的標準分層結構。

該規範中定義了各層的職責,其中最重要的兩層Service層和Manager層是這樣規範的(以下兩層解釋摘抄自《Java 開發手冊》):

Service層

相對具體的業務邏輯服務層。

Manager層

通用業務處理層,它有如下特徵:

  • 對第三方平臺封裝的層,預處理返回結果及轉化異常信息。
  • 對Service層通用能力的下沉,如緩存方案、中間件通用處理。
  • 與DAO層交互,對多個DAO的組合複用。

image

圖3 傳統的分層結構

阿里文娛早期的項目分層也基本都採用這種架構形式。上面的分層並沒有問題,但是這種分層架構採用的是包的形式進行的層與層的隔離,需要每一位開發同學理解並且自覺遵守以上規範,但是在實際工作中我們發現很多同學對Service層和Manager層的區別並不是特別的清楚,即使清楚的同學大部分也並沒有完全遵守手冊中的規範,這種現象導致Manager層除了沉底一些通用能力以外和Service層並沒有什麼本質區別。

在實際的業務代碼中Service層和Manager層都充斥了大量的第三方依賴,對系統的穩定性有很大的影響。每依賴一個第三方服務都要各種異常問題,這些異常處理的代碼往往會和業務代碼混在一起,當這種代碼多了以後會使代碼的可讀性非常差。

阿里文娛業務的複雜度提升很快,業務迭代速度也很快, Service層和Manager層代碼量迅速膨脹,業務邏輯變得越來越複雜。在這種業務場景下,大文娛引入了領域驅動設計並設計了一套完整的領域驅動模型評估與演進的解決方案來輔助開發同學將領域驅動設計的思想真正的落地。

四 文娛領域驅動設計實踐

領域驅動設計的關鍵在於識別業務的模型,而模型又是會隨着業務的發展而演進的,對於新的業務來說能效平臺提供了業務模型分析的功能,開發同學可以在能效平臺設計並搭建自己的領域模型,搭建出來後能效平臺可以評估領域模型設計的是否合理,如果模型設計合理則可以基於以上設計的模型符合領域模型規範的代碼。對於已有應用,能效平臺設計了一套領域註解並以SDK的形式提供出去:

  • 第一步:開發同學按照領域設計的原則對業務代碼進行分析並打上註解。
  • 第二步:能效平臺可自動掃描該項目並收集該項目中的領域模型。
  • 第三步:模型收集後,開發同學可以在能效平臺改進業務模型並重新按照領域模型的規範生成代碼。

完整流程如下圖所示:

image

圖4 領域模型的生命週期

1 模型採集

對於已有的準備重構的應用,我們設計了一套領域模型的註解,開發同學可以將註解加到對應的類、屬性、方法上。當系統是按數據模型落地而不是按領域模型的方式落地時,可以先找到系統的數據模型,然後在能效平臺對數據模型進行組織生成領域模型。

image

圖5 領域模型註解

2 模型搭建

對於新應用或者已經進行完模型採集的應用,開發同學可以在能效平臺進行模型的搭建和修改,如圖6所示。

image

圖6 領域模型

3 健康度評估

對於已經搭建完的模型能效平臺,根據領域驅動設計的規範創建了一套完整的校驗規則,模型搭建完成在生成腳手架之前會根據校驗規則進行打分,當打分通過時可以將模型生成腳手架。

image

圖7 模型校驗

4 腳手架生成

當模型搭建完畢並且校驗通過後可以將模型生成腳手架,其代碼結構是按照六邊形架構的標準生成的,六邊形架構也成爲端口與適配器架構,該架構的思想是將內部核心的領域邏輯與外界依賴進行隔離,這裏的依賴是指所有對其他微服務的依賴、http的依賴、數據庫依賴、緩存依賴、消息中間件依賴等等,所有的這些依賴都通過適配器進行轉換成應用可理解可識別的最小化信息。

在實際的項目中,每種依賴都要考慮各種異常情況並進行處理,而這些處理實際上並不數據領域邏輯,卻耦合到了業務代碼裏,當這種依賴多了對系統的穩定性會產生很大的影響,傳統的分層架構雖然也會讓我們將自身的領域邏輯和依賴進行分離,在阿里巴巴規範手冊中提到所有的依賴都應該放到Manager層,但是這種規範是非常容易被打破的。六邊形架構從應用分層上讓我們更容易去遵守這樣的規範。

image

圖8 六邊形架構

根據六邊形架構的指導思想,在實際的應用分層中一般劃分爲四層,分別是:

  • 用戶接口層:負責用戶展現相關的邏輯。
  • 應用層:負責對一個用例進行流程編排(將接口用例分成若干個步驟,但是不負責每步的具體實施)。
  • 領域層:負責實現核心的領域邏輯即業務邏輯(負責實現具體的業務邏輯)。
  • 基礎設施層:所有依賴的具體實現。

但是從應用架構的角度看,層級組織形式可以分爲兩種:

傳統分層架構

如圖9左側,這種分層架構是Evic Evans在《Domain-Driven Design : Tackling Complexity in the Heart of Software》中提出的,其中用戶接口層、應用層、領域層可直接依賴基礎設施層,與圖3的傳統架構並無本質區別,因爲所有層都直接依賴了基礎設施層。這種方式需要強制開發同學將所有的依賴進行下沉,隨着時間的推移這種規範非常容易被打破。

image

圖9 層依賴關係

依賴倒置的分層架構

如圖9右側,這種分層架構是依賴倒置的分層架構,特點是:

  • 基礎設計層可直接依賴其他三層,反之則不行。
  • 用戶接口層、應用層、領域層如果要使用基礎設施層中的能力,只能通過IOC的方式進行依賴注入,這也遵從了面向對象編程中的依賴倒置原則。

當開發同學要在以上三層中直接引用第三方依賴時,是找不到具體的類信息的,也就是不能import。同時這種方式對單元測試的規範也可以起到很大的作用,當我們編寫單元測試時可以爲領域層注入一個測試運行時的依賴,這樣應用運行單元測試可以不依賴下游服務,在代碼層面上也更加規範。

五 總結

經典的三層或多層架構雖然是目前最普遍的架構,但是在隔離方面做得並不夠好。在業務架構選型時要結合自身業務特點,而不能千篇一律的選擇某一種業務架構,合適的業務架構可以延長項目的生命週期,降低項目的重構頻率,最終達到降低人力成本的目的。

【雲棲號在線課堂】每天都有產品技術專家分享!
課程地址:https://yqh.aliyun.com/live

立即加入社羣,與專家面對面,及時瞭解課程最新動態!
【雲棲號在線課堂 社羣】https://c.tb.cn/F3.Z8gvnK

原文發佈時間:2020-07-27
本文作者:阿里巴巴文娛技術
本文來自:“阿里技術公衆號”,瞭解相關信息可以關注“阿里技術

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章