天天看點

領域驅動設計-從分層架構聊起

一、概述

對于比較複雜的業務流程,傳統的分層架構等在後續代碼可擴充性,可維護性,可測試上存在很大的問題,最近也在學習和研究領域模型相關的設計,實踐總結一下。

代碼倉庫:Jmqtt,隻關注其中的jmqtt-admin子產品即可,歡迎老鐵給個star

二、傳統的分層架構

如圖:

領域驅動設計-從分層架構聊起

這是一個極簡的三層架構模式,每層的關系和職責大約是:

  • WEB層(Controller層):提供http接口給外部,處理參數的接收和響應;依賴業務層;與之類似的層包括:Gateway層,OpenAPI層,服務層(提供RPC給其他服務)等
  • 業務層(Service層):負責處理業務邏輯,包括參數校驗,資料處理轉換,業務邏輯處理,與資料層互動等;依賴資料層
  • 資料層(DAO層):負責處理資料持久化,資料緩存等;與之類似的層包括:整合層(基礎依賴層,處理MQ,定時任務等基礎依賴),外部依賴層(依賴其他服務提供的RPC服務接口,http接口等服務)
  • 通用層:工具類等處理

三、領域驅動設計的六邊形架構

領域驅動設計-從分層架構聊起

六邊形架構網上已經有很多解釋和說明了,這裡我說下我的了解:

  • 領域層(domain層):處理領域模型的地方,在領域設計中的實體,值對象,領域服務,聚合根,聚合等都放在這裡。不依賴任何外部子產品,提供接口(adapter)給外部實作進行互動。
  • 應用層(application層):依賴領域層,可對标三層架構中的業務層進行了解,不過領域設計中的應用層隻負責業務流程編排,不負責資料完整性校驗,業務邏輯處理等。依賴領域層,調用領域層的領域服務或聚合根進行業務編碼
  • 資料層(dal層):處理資料持久化的邏輯,實作領域層的adapter接口,依賴領域層。
  • 整合層(intergration層):處理外部依賴,包括其他服務提供的RPC服務,外部Http接口服務等,實作領域層adapter接口,依賴領域層。這裡還有一層防腐層(ACL),主要是處理對第三方依賴的強依賴,防止因第三方服務不可用或服務接口資料改動,導緻領域服務不可用。
  • 基礎依賴層(intergration層):處理MQ,定時任務等基礎依賴,可與整合層放在一起,主要處理第三方中間件依賴等,實作領域層的adapter接口,依賴領域層。
  • 接口服務層(facade/client層):主要暴露對外提供的接口服務,封裝DTO,CQRS,領域事件對象等,不依賴任何外部服務,領域層依賴該子產品,放在這裡主要是為了說明。
  • 測試層(test層):主要負責單元測試和內建測試,依賴所有層,放在這裡主要是為了說明。

其它還沒标明的一些層:

  • WEB層(controller層):依賴領域層,提供http接口服務,其它類似Gateway層等
  • 通用層(common層):各層的工具在各層自行封裝,降低依賴。也可以引入一個通用Common層,比如日志處理等。

四、實踐案例

背景:jmqtt-admin是一個iot mq的管理平台,背景主要是提供Iot裝置的管理,監控,資料采集等。

下面是jmqtt-admin的子產品設計:

領域驅動設計-從分層架構聊起

目前代碼整個管理平台還在開發中,整套後端代碼會采用領域設計的方式開發,歡迎持續關注,

附子產品依賴圖:

Gateway依賴WEB層,可複用WEB層的攔截器等進行處理。

領域驅動設計-從分層架構聊起

五、聊聊差別

分層架構:

  • 一般是資料模組化管道,接到業務需求後,技術手段上首先是進行資料模組化,再進行開發。
  • 重業務層,一般沒有領域的概念,重業務層意味着基本所有核心業務都是在業務層解決的,對下直接依賴資料層,資料層上一般是提供接口和資料DO對象,導緻切換底層資料源時,上層業務層可能也需要做一些改動(耦合高)。同理,改動業務層也可能涉及底層依賴的改動
  • 擴充比較難:每次改動都需要改動業務層,若業務複雜,可能一個方法裡包含了非常多的邏輯,包括:驗參,處理業務邏輯,請求第三方依賴擷取資料,資料轉換,資料持久化等等
  • 較難測試:對于一個業務,往往業務大了,想要測試這個業務方法時,需要将業務邏輯依賴的所有服務都啟動起來,單測比較麻煩。

領域驅動設計:

  • 表現為領域驅動設計:由技術專家+業務專家共同模組化(梳理業務流程,對焦通用語言,劃分領域邊界),技術上表現先開發領域層,定義領域模型和接口服務,再開發其他具體實作
  • 重領域層,核心變動和經常改變的應該都是在領域層,其他層變動不應該影響領域層,領域層的變動應該隻影響上層應用層。領域層的實體除了負責簡單資料屬性外,還要處理業務邏輯
  • 較為複雜,需要和前期學習成本:如圖,比較複雜。在前期業務簡單時,開發速度比分層架構慢,但是後續可擴充性和可維護性及可測試行強很多(領域模型區分了變化與不變的邊界。頻繁變化的邏輯應該都在領域層)
  • 不一定适用所有業務應用,不過領域劃分的思想适合用來劃分微服務,限制相關開發,一旦形成約定,對于代碼了解成本也會降低一些。