1. 程式人生 > >領域驅動設計-分享

領域驅動設計-分享

技術問題 詳細分析 上下文 mage oot class 頁面 val 約束

概述

領域驅動不是純粹的技術問題,領域建模(建立數據表只是一部分)是領域專家(客戶/產品團隊)和開發人員溝通努力、抽象的的結果。

領域建模的目的是,經過有效的溝通、詳細分析、 良好設計可以更好的適應未來的變化。

領域驅動設計的核心是建立正確的領域模型。

面向人員

後端開發人員、產品人員

一、背景

  1. 領域驅動設計是什麽?

    領域驅動設計的核心是建立正確的領域模型,正確的反應業務,並適應變化。

  2. 為什麽建立一個領域模型是重要的

    (1). 領域模型是具有邊界的領域抽象,反映了領域業務需求的本質,邊界指只領域內所關註的部分;

    (2). 領域模型只反映業務,和任何技術實現無關, 包括實體概念(如商品)和過程概念(資金轉賬);

    (3).領域模型確保業務邏輯內聚在一個模型中,幫助可理解和重用;

    (4). 領域模型幫助開發人員平滑轉換為軟件構造;

    (5).領域模型貫穿軟件分析設計開發整個過程,領域專家、設計、開發人員始終保持溝通,共享信息,確保軟件真正滿足需求;

    (6).建立正確的領域模型並不簡單,需要領域專家、設計、開發人員積極溝通共同努力,然後才能使大家對領域(業務需求)的認識不斷深入,從而不斷細化和完善領域模型;

    (7).領域模型是整個軟件的核心,是最有價值和最具競爭力的部分;設計足夠精良且符合業務需求的領域模型能夠更快速的響應需求變化;

  3. 領域建模時思考問題的角度

二、概念

領域驅動分層

技術分享圖片

User Interface 用戶界面層

在PC頁面、APP界面、WebAPI接口展示數據;

發送命令給應用層要求其執行某個用戶命令;

Application 應用層

定義系統要完成的所有任務,對用戶界面層提供應用功能。對內調用領域層(領域對象或領域服務)完成業務邏輯,應用層不包含業務邏輯。

Domain 領域層

負責表達業務概念,業務狀態信息以及業務規則,領域模型處於這一層,是業務軟件的核心。

限界上下文

限界上下文是個高內聚的領域模型(例訂單模塊),是未來系統做水平拆分的關鍵,可以說就是將一個限界上下文模型拆分升級為一個子系統。

開發人員可以簡單理解,限界上下文可以轉換成代碼,放在一個高內聚的dll項目;

AggregateRoot 聚合根

聚合,它通過定義對象之間清晰的所屬關系和邊界來實現領域模型的內聚,並避免了錯綜復雜的難以維護的對象關系網的形成。聚合定義了一組具有內聚關系的相關對象的集合,我們把聚合看作是一個修改數據的單元。

聚合的特點:

(1). 每個聚合有一個根和一個邊界,邊界定義了一個聚合內部有哪些實體或值對象,根是聚合內的某個實體;

(2). 聚合內部的對象之間可以相互引用,但是聚合外部如果要訪問聚合內部的對象時,必須通過聚合根開始導航,絕對不能繞過聚合根直接訪問聚合內的對象,也就是說聚合根是外部可以保持 對它的引用的唯一元素;

(3). 聚合內除根以外的其他實體的唯一標識都是本地標識,也就是只要在聚合內部保持唯一即可,因為它們總是從屬於這個聚合的;

(4). 聚合根負責與外部其他對象打交道並維護自己內部的業務規則;

(5). 基於聚合的以上概念,我們可以推論出從數據庫查詢時的單元也是以聚合為一個單元,也就是說我們不能直接查詢聚合內部的某個非根的對象;

(6). 聚合內部的對象可以保持對其他聚合根的引用;
刪除一個聚合根時必須同時刪除該聚合內的所有相關對象,因為他們都同屬於一個聚合,是一個完整的概念;

如何識別聚合及聚合根?

我覺得我們可以先從業務的角度深入思考,然後慢慢分析出有哪些對象是:
有獨立存在的意義,即它是不依賴於其他對象的存在它才有意義的;
可以被獨立訪問的,還是必須通過某個其他對象導航得到的;

如何識別聚合根?

如果一個聚合只有一個實體,那麽這個實體就是聚合根;如果有多個實體,那麽我們可以思考聚合內哪個對象有獨立存在的意義並且可以和外部直接進行交互。

Entity 實體

不能獨立存在的業務對象,必須掛在聚合根上。

ValueObject 值對象

定義:在領域中,不需要唯一鍵標識的對象,包括:

常見的值對象:

字符串常量;

枚舉;

無主鍵約束的引用對象;

如果有兩個Customer的地址信息是一樣的,我們就會認為這兩個Customer的地址是同一個。也就是說只要地址信息一樣,我們就認為是同一個地址Address。

Domain Service 領域服務

領域中的一些概念不太適合建模為對象,即歸類到實體對象或值對象,因為它們本質上就是一些操作,一些動作,而不是事物。這些操作或動作往往會涉及到多個領域對象。

領域服務一個很重要的功能就是可以避免領域邏輯泄露到應用層。

Domain Event 領域事件

容易降低耦合,方便做到高擴展性;

領域聚合根之間很難做到強一致性,大多數都是最終一致性;

Infrastructure 基礎設施層

本層為其他層提供通用的技術能力;提供了層間的通信;為領域層實現持久化機制;總之,基礎設施層可以通過架構和框架來支持其他層的技術需求;

三、案例分析

那些是聚合、聚合根、實體、值對象?

技術分享圖片

註意

開發人員/團隊需要和產品團隊/客戶保持充分的溝通。

領域驅動設計-分享