主要是在開發過程當中,我的對於領域驅動設計的實踐感悟和總結;也是對新進開發人員的培訓資料;但願對關注DDD的童鞋有所幫助。數據庫
領域驅動不是純粹的技術問題,領域建模(創建數據表只是一部分)是領域專家(客戶/產品團隊)和開發人員溝通努力、抽象的的結果。後端
領域建模的目的是,通過有效的溝通、詳細分析、 良好設計能夠更好的適應將來的變化。架構
領域驅動設計的核心是創建正確的領域模型。app
後端開發人員、產品人員框架
領域驅動設計是什麼?dom
領域驅動設計的核心是創建正確的領域模型,正確的反應業務,並適應變化。設計
爲何創建一個領域模型是重要的對象
(1). 領域模型是具備邊界的領域抽象,反映了領域業務需求的本質,邊界指只領域內所關注的部分;blog
(2). 領域模型只反映業務,和任何技術實現無關, 包括實體概念(如商品)和過程概念(資金轉帳);接口
(3).領域模型確保業務邏輯內聚在一個模型中,幫助可理解和重用;
(4). 領域模型幫助開發人員平滑轉換爲軟件構造;
(5).領域模型貫穿軟件分析設計開發整個過程,領域專家、設計、開發人員始終保持溝通,共享信息,確保軟件真正知足需求;
(6).創建正確的領域模型並不簡單,須要領域專家、設計、開發人員積極溝通共同努力,而後才能使你們對領域(業務需求)的認識不斷深刻,從而不斷細化和完善領域模型;
(7).領域模型是整個軟件的核心,是最有價值和最具競爭力的部分;設計足夠精良且符合業務需求的領域模型可以更快速的響應需求變化;
領域建模時思考問題的角度
在PC頁面、APP界面、WebAPI接口展現數據;
發送命令給應用層要求其執行某個用戶命令;
定義系統要完成的全部任務,對用戶界面層提供應用功能。對內調用領域層(領域對象或領域服務)完成業務邏輯,應用層不包含業務邏輯。
負責表達業務概念,業務狀態信息以及業務規則,領域模型處於這一層,是業務軟件的核心。
限界上下文是個高內聚的領域模型(例訂單模塊),是將來系統作水平拆分的關鍵,能夠說就是將一個限界上下文模型拆分升級爲一個子系統。
開發人員能夠簡單理解,限界上下文能夠轉換成代碼,放在一個高內聚的dll項目;
聚合,它經過定義對象之間清晰的所屬關係和邊界來實現領域模型的內聚,並避免了錯綜複雜的難以維護的對象關係網的造成。聚合定義了一組具備內聚關係的相關對象的集合,咱們把聚合看做是一個修改數據的單元。
(1). 每一個聚合有一個根和一個邊界,邊界定義了一個聚合內部有哪些實體或值對象,根是聚合內的某個實體;
(2). 聚合內部的對象之間能夠相互引用,可是聚合外部若是要訪問聚合內部的對象時,必須經過聚合根開始導航,絕對不能繞過聚合根直接訪問聚合內的對象,也就是說聚合根是外部能夠保持 對它的引用的惟一元素;
(3). 聚合內除根之外的其餘實體的惟一標識都是本地標識,也就是隻要在聚合內部保持惟一便可,由於它們老是從屬於這個聚合的;
(4). 聚合根負責與外部其餘對象打交道並維護本身內部的業務規則;
(5). 基於聚合的以上概念,咱們能夠推論出從數據庫查詢時的單元也是以聚合爲一個單元,也就是說咱們不能直接查詢聚合內部的某個非根的對象;
(6). 聚合內部的對象能夠保持對其餘聚合根的引用;
刪除一個聚合根時必須同時刪除該聚合內的全部相關對象,由於他們都同屬於一個聚合,是一個完整的概念;
我以爲咱們能夠先從業務的角度深刻思考,而後慢慢分析出有哪些對象是:
有獨立存在的意義,即它是不依賴於其餘對象的存在它纔有意義的;
能夠被獨立訪問的,仍是必須經過某個其餘對象導航獲得的;
若是一個聚合只有一個實體,那麼這個實體就是聚合根;若是有多個實體,那麼咱們能夠思考聚合內哪一個對象有獨立存在的意義而且能夠和外部直接進行交互。
不能獨立存在的業務對象,必須掛在聚合根上。
定義:在領域中,不須要惟一鍵標識的對象,包括:
常見的值對象:
字符串常量;
枚舉;
無主鍵約束的引用對象;
若是有兩個Customer的地址信息是同樣的,咱們就會認爲這兩個Customer的地址是同一個。也就是說只要地址信息同樣,咱們就認爲是同一個地址Address。
領域中的一些概念不太適合建模爲對象,即歸類到實體對象或值對象,由於它們本質上就是一些操做,一些動做,而不是事物。這些操做或動做每每會涉及到多個領域對象。
領域服務一個很重要的功能就是能夠避免領域邏輯泄露到應用層。
容易下降耦合,方便作到高擴展性;
領域聚合根之間很難作到強一致性,大多數都是最終一致性;
本層爲其餘層提供通用的技術能力;提供了層間的通訊;爲領域層實現持久化機制;總之,基礎設施層能夠經過架構和框架來支持其餘層的技術需求;
開發人員/團隊須要和產品團隊/客戶保持充分的溝通。