基于DDD領域驅動設計的思想,在開發具體系統時,需要先建立不同的層級包,主要是梳理不同層面(應用層,領域層,基礎設施層,展示層)包括的功能目錄,每一個層面應該包括哪些模塊,本例所講述的分層是DDD落地方案中常用的一種(參考),且本例適當做了調整和細化,詳細分層目錄參考下圖:
1. 展示層
展現層(用戶介面層)(Presentation Layer):負責以Restful的格式接受Web請求,然后將請求路由給Application層執行,并回傳視圖模型(View Model),其載體通常是DTO(Data Transfer Object),* userinterfaces: 展示層,又稱用戶介面層 * 用戶介面層為外部用戶訪問底層系統提供互動界面和資料表示, * 用戶介面層在底層系統之上封裝了一層可訪問外殼,為特定型別的外部用戶(人或計算機程式)訪問底層系統提供訪問入口,并將底層系統的狀態資料以該型別客戶需要的形式呈現給它們, * * 用戶介面層有兩個任務: * 從用戶處接收命令操作,改變底層系統狀態; * 從用戶處接收查詢操作,將底層系統狀態以合適的形式呈現給用戶, * * 本例用戶介面層包括如下子模塊: * 命令目錄(command): 物件命名為XxxCommand,指呼叫方明確想讓系統操作的指令,其預期是對一個系統有影響,也就是寫操作,通常來講指令需要有一個明確的回傳值(如同步的操作結果,或異步的指令已經被接受), * 查詢目錄(query): 物件命名為XxxQuery,指呼叫方明確想查詢的東西,包括查詢引數、過濾、分頁等條件,其預期是對一個系統的資料完全不影響的,也就是只讀操作, * 事件目錄(event): 物件命名為XxxEvent,指一件已經發生過的既有事實,需要系統根據這個事實作出改變或者回應的,通常事件處理都會有一定的寫操作,事件處理器不會有回傳值,這里需要注意一下的是,
* Application層的Event概念和Domain層的DomainEvent是類似的概念,但不一定是同一回事,這里的Event更多是外部一種通知機制而已, * 回傳資料物件目錄(dto): 物件命名為XxxDto,作為ApplicationService的出參 * 控制層(Controller): 提供restful介面,供外部系統呼叫 * * 規范: * ApplicationService的介面入參只能是一個Command、Query或Event物件,CQE物件需要能代表當前方法的語意,唯一可以的例外是根據單一ID查詢的情況,可以省略掉一個Query物件的創建 * CQE,Dto,都是Value Object,但是從語意上來看有比較大的差異,主要是從命名上區別出來, * CQE:CQE物件是ApplicationService的輸入,是有明確的“意圖”的,所以這個物件必須保證其"正確性",為驗證部分欄位的格式,必填性,可基于Spring Validation等模式做基礎資料驗證, * DTO:Dto物件只是資料容器,只是為了和外部互動,所以本身不包含任何邏輯,只是貧血物件,
2. 應用層
應用層(Application Layer):主要負責獲取輸入,組裝背景關系,做輸入校驗,呼叫領域層做業務處理,如果需要的話,發送訊息通知,當然,層次是開放的,若有需要,應用層也可以直接訪問基礎實施層,* application 應用層 * 相對于領域層,應用層是很薄的一層,應用層定義了軟體要完成的任務,要盡量簡單. * 它不包含任務業務規則或知識, 為下一層的領域物件協助任務、委托作業,這一層也很適合寫一些任務處理,訊息處理 * 它沒有反映業務情況的狀態,但它可以具有反映用戶或程式的某個任務的進展狀態, * * 對外:為展現層提供各種應用功能(service), * 對內:呼叫領域層(領域物件或領域服務)完成各種業務邏輯任務 * * 事件(event): 物件命名為XxxEvent,跨聚合根,或部分業務處理完成后,需要通知其他模塊的,本例采用 Spring event模式,本例是將領域事件放在應用層的, * 應用服務(service): 物件命名為XxxService,應用層的服務 * * 一個應用層通常包括以下三種服務: * * 業務處理類:XxxCommandService * 業務查詢類:XxxQueryService * 業務事件類:XxxEventService特別說明:一個物體處理完成后,若存在副作用,可基于事件模式處理,關于事件模塊到底是放置在領域層還是應用層,網上存在不同的模式(參考網址:DDD-領域事件),本例是基于Spring Event模式,放在應用層的,
3. 領域層
領域層(Domain Layer):主要是封裝了核心業務邏輯,并通過領域服務(Domain Service)和領域物件(Entities)的函式對外部提供業務邏輯的計算和處理,* domain 領域層 * 領域層主要負責表達業務概念,業務狀態資訊和業務規則,是一個純記憶體化的操作, * Domain層是整個系統的核心層,幾乎全部的業務邏輯會在該層實作,領域層不關注資料是如何落地存盤的,領域層也不直接呼叫底層倉庫介面保存資料, * 領域模型層主要包含以下的內容: * * 物體(Entities): 物件命名為XxxE,具有唯一標識的物件,所有物體統一用E作為后綴,如PersonE * 工廠(factory): 介面命名規則為XxxFactory,創建復雜的物體,聚合根,只做創建處理 * 值物件(vo): 物件命名為XxxV,無需唯一標識的物件,所有值對像統一同V作為后綴 ,如PersonV,物體的主鍵編碼以Id結尾 * 領域服務(Domain Services): 介面命名規則為XxxDomainService,一些行為無法歸類到物體物件或值物件上,本質是一些操作,而非事物(與本例中domain/service包下的含義不同) * 倉儲(Repository): 介面命名規則為XxxRepository,創建復雜物件,隱藏創建細節,提供查找和持久化物件的方法,本層僅撰寫倉庫的介面,具體實作再基礎層 * 聚合/聚合根(Aggregates,Aggregate Roots): 物件命名為XxxA,聚合是指一組具有內聚關系的相關物件的集合,每個聚合都有一個root和boundary,所有聚合統一用A作為后綴,如PersonA *
4. 基礎實施層
基礎實施層(Infrastructure Layer)主要包含Tunnel(資料通道)、防腐層,Config和Common,這里我們使用Tunnel這個概念來對所有的資料來源進行抽象,這些資料來源可以是資料庫(MySQL,NoSql)、搜索引擎、檔案系統、也可以是SOA服務等;Config負責應用的配置;Common是通用的工具類,* infrastructure 基礎實施層 * 向其他層提供 通用的 技術能力(比如工具類,第三方庫類支持,常用基本配置,資料訪問底層實作) * 基礎實施層主要包含以下的內容: * 為應用層 傳遞訊息(比如通知) * 為應用層 提供持久化機制(最底層的實作) * * 防腐層(acl): 物體對接外部系統,物體與外部系統之間,不同領域之間,不同的引數轉換,語意轉換等 * 轉換層(assembler): 資料轉換工具類,如Dto轉換為物體,物體轉換為資料表pojo物件,基于org.mapstruct.Mapper實作 * 倉庫層(repository): 倉庫實作層,物體與DB之間存盤的功能層 * 例外管理(exception): 封裝具體業務的例外處理資訊 * 配置模塊(config): 封裝配置資訊,包括一些基礎靜態欄位,基于阿波羅等獲取的配置資訊 * 列舉模塊(enum): 封裝該模塊的列舉資訊 * 資料庫映射的基礎資料物件(database): 命名規則為:XxxDo,資料表翻譯為java基礎的pojo物件
5.專案分層
一個微服務里,通常包括多個不同的領域業務,一個領域業務基于DDD的模式,通常都包括上述的分層模塊,為了區分不同的領域業務,有兩種方案建立包的層級,- DDD層級分類:基于分層包,在每一個包下面,新建具體業務的名稱,如在application.service包下面建立退款,售后補償業務,建立兩個分別為application.service.refund(退款包),application.service.compensate(售后包),
- 業務分類:基于業務分層,在四層包的前提下,每一個業務均包括DDD的分層包,如下圖所示:
本例選用的方案2,便于歸類業務在各個層的模塊代碼,最后層級結構確定下來后,每個層只負責該層應該負責的功能,不可混用,濫用,好的設計需要開發人員遵守一定的規則,關于層級劃分,沒有絕對的標準,可參考開源COLA 4.0或其他架構學習,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/341684.html
標籤:Java
上一篇:你一定不知道的Unsafe用法
下一篇:設計模式系列-單例模式
