緣起
哈嘍大家周四好!又是開心的一天,時間過的真快,我們的 《從壹開始 .net core 2.1 + vue 2.5 》前后端分離系列共 34 篇已經完結了,當然以后肯定還會有更新和修改,直接在文章內更新,並在文章開頭做提醒,如果有大的改動或者新功能,會在目錄頁進行重點說明(可能簡書的更新速度沒有博客園快,如果有任何疑問,可以先看博客園的文章,就是上邊的這個地址👆)。如果你是剛看到我的文章,而且恰好對.net core 不是很明白,或者想了解下如何前后端完全分離的,可以先看看上一個系列,我已經把 .net core 和 vue 的內容明顯分開了,同時也把 vue 的基礎部分和入門教程兩個部分進行說明,相信大家都能看的明白。
關於這一個系列,我想了很久,本來想開下 React 系列的,但是群里的小伙伴的反映,.net 后端還有很多東西,而且好多小伙伴反映課本太苦澀,看不進去,文檔又太少,國內的大神好像也不太照顧我們這些小學生,特別是很少通過代碼的形式講解,那所以我就開了這個系列,雖然感覺會坎坷波折,本系列會從一個空的 Solution 到一個 完整 Project 的過程,具體的會在下邊的計划書中詳細說明,大家可以一會兒了解下,當然,框架本來就很見仁見智,思想設計更是沒有常規法去定義,可能會有人不同意,老張希望如果有不同意見,別僅僅只是點擊一下反對,可以發表下評論嘛,也算是給 .net 生存環境做點兒貢獻,當然這個是練習項目,實際情況還要按照公司的要求來寫,甚至公司都用不到(但是可能會面試的時候問到),一些小伙伴就會問,那我為啥要學,嗯~~~要是這么問,我也不知道如何回答了 [苦笑] ,就好像健身一樣。
我給這個項目取名:ChristD3,意思是聖誕節DDD,希望到聖誕節的時候可以完結,因為年底手中工作比較多,所以不會每天都寫,但是每周肯定會有更新,也希望大家可以多多提意見,為了.net 的生存環境點贊加油吧!其實如果你已經開完了我寫的上一個系列,你會發現其實上一個系列已經有 DDD 的影子了,不信?看完本文你就會知道了。
簡單強調:
1、本系列重點通過代碼進行說明,那些苦澀的概念可能比較少,特別是本文,是簡要說明,具體的詳細內容在之后文章中體現。
2、本系列只是對知識點進行講解,重點在說明新知識上,只是一個很小的框架,數據也很簡單,可能還是一個簡單的個人博客之類的,請不要和企業級項目對比。
3、本系列還是沿用上一個系列的宗旨:旨在拋磚引玉,想要學會還得自己多思考,文中會有兩本參考書,可以看看。
目錄:
源碼 Github
.NET CORE 源碼:
Github: https://github.com/anjoy8/ChristDDD
Gitee : https://gitee.com/laozhangIsPhi/ChristDDD
以后更新的文章會在這里一一更新:
- 一 ║ D3模式設計初探 與 我的計划書
- 二 ║ DDD入門 & 項目結構粗搭建
- 三 ║ 簡單說說:領域、子域、限界上下文
- 四 ║一個讓你明白DDD的小故事 & EFCore初探
- 五 ║聚合:實體與值對象 (上)
- 六 ║聚合 與 聚合根 (下)
- 七 ║項目第一次實現 & CQRS初探
- 八 ║剪不斷理還亂的 值對象和Dto
- 九 ║從軍事故事中,明白領域命令驗證(上)
- 十 ║領域驅動【實戰篇·中】:命令總線Bus分發(一)
- 十一 ║ 基於源碼分析,命令分發的過程(二)
- 十二 ║ 核心篇【下】:事件驅動EDA 詳解
- 十三 ║ 當事件溯源 遇上 粉絲活動
一、今天要實現紅色的部分
二、DDD領域驅動設計的前世今生
好多小伙伴都在說,聽DDD都聽了好幾年了,感覺就像是空氣一樣,一直在身邊,可是一直摸不着,雖然有時候用到一些,可都是無法具體深入的對其描述和總結,那領域驅動設計到底是怎么來的呢,在早期項目開發中,我們主要就是單系統來進行開發,很多的模板都是揉在一起,其實現在咱們平時用的最多的MVC架構也有這樣的問題,然后近來演化出的前后端分離,是從協同開發的角度方向去改善單系統問題,而DDD則是從后端整體框架中,對項目進行整合,剝離,細分和聯系通訊等等,這樣面向領域驅動設計就出現了。
1、DDD領域驅動設計知多少
首先要知道DDD是一種開發理念,核心是維護一個反應領域概念的模型(領域模型是軟件最核心的部分,反應了軟件的業務本質),然后通過大量模式來指導模型設計與開發。
DDD的一般過程是:首先通過軟件需求規格說明書或原型生成一個領域模型(類、類的屬性、類與類之間的關系);然后根據模式(應該如何分層?、領域邏輯寫在哪?與持久化如何交互?如何協調多對象領域邏輯?如何實現邏輯與數據存儲解耦等)指導來實現代碼模型。
DDD中最核心的是Domain Model(領域模型),和領域模型相對的是事務腳本。領域模型和事務腳本說到底就是面向對象和面向過程的區別。
如果感覺上邊的理解有點兒苦澀,這里舉個栗子:
我認為任何一個系統都會屬於某個特定的領域,比如論壇是一個領域,只要你想做一個論壇,那這個論壇的核心業務是確定的,比如都有用戶發帖、回帖等核心基本功能。比如電商平台、普通電商系統,這種都屬於網上電商領域,只要是這個領域的系統,那都有商品瀏覽、購物車、下單、減庫存、付款交易等核心環節。所以,同一個領域的系統都具有相同的核心業務,因為他們要解決的問題的本質是類似的。
因此,我們可以推斷出,一個領域本質上可以理解為就是一個問題域,只要是同一個領域,那問題域就相同。所以,只要我們確定了系統所屬的領域,那這個系統的核心業務,即要解決的關鍵問題、問題的范圍邊界就基本確定了。
關於電商系統大家肯定都很了解了,什么商品模塊,用戶模板,訂單模板,等等等等,這個就是領域模型的一個體現,網上看到一個很好的文章,他對普通電商的訂單中心進行建模,如圖:
2、領域驅動設計整體架構
那從整體架構上來說,主要分成以下四個部分,具體的在下一講的項目整體搭建中會詳細說明:
- Presentation Layer:表現層,負責顯示和接受輸入;
- Application Layer(Service):應用層,很薄的一層,只包含工作流控制邏輯,不包含業務邏輯;
- Domain Layer(Domain):領域層,包含整個應用的所有業務邏輯;
- Infrastructure Layer:基礎層,提供整個應用的基礎服務;
DDD領域驅動設計的優點就包括:
1.從技術維度實現分層:能夠在每層關注自己的事情,比如領域層關注業務邏輯的事情,倉儲關注持久化數據的事情,應用服務層關注用例的事情,接口層關注暴露給前端的事情。
2.業務維度:通過將大系統划分層多個上下文,可以讓不同團隊和不同人只關注當前上下文的開發。
3.時間維度:通過敏捷式迭代快速驗證,快速修正。
3、如何划分領域聚合
這里隨便舉個栗子:
公司部門權限小系統,用戶表 User、角色表 Role、用戶角色關系表 UserRole、部門表 Department、菜單表 Menu、菜單角色關系表 MenuRole,共六個表,
首先呢,根據我的想法,只要對一個模型操作,就必須建倉儲 Repository ,那它就是一個聚合,所以:聚合和倉儲基本是一對一的,有一個倉儲就是一個聚合。
所以現在有四個聚合了:
聚合1:Department
聚合2:Menu、MenuRole、Role 三個, 聚合根是 Menu
聚合3:User、UserRole、Department、Role 四個,聚合根是 User。
聚合4:Role、User、UserRole、MenuRole、Menu 五個,聚合根是 Role。
然后再從關系表中看,用戶和角色是多對多的關系,所以需要把 UserRole 作為一個新的聚合
聚合5:UserRole、User、Role 三個, 聚合根是 UserRole
這里存個疑,MenuRole 需不需要一個倉儲,也就是一個聚合?
4、有哪些資料可以參考
書籍:
2004年,Eric Evans的《領域驅動設計——軟件核心復雜性應對之道》
2014年,Vaughn Vernon的《實現領域驅動設計》,個人推薦
編者按:
1、本項目我是借鑒了 https://github.com/EduardoPires/EquinoxProject 來講解的,請支持原作者!因為他沒有文檔,所以我就寫了這個系列。
2、可能你會說我是抄襲,但是我自己寫的時候,結構不是這樣的,我當時是這么寫的(如果你和我下邊的分層一樣,那就證明我不是瞎說的了):
應用層:除了Service和IService、DTO、還有使用 CQRS 方法的查詢、接受的命令,事件驅動的通信(集成事件),但是沒有業務規則;
領域層:這里主要放的是領域實體、值對象、聚合和事件模型、Bus等;
基礎層:就是ORM的持久化相關;
U I 層:顯示頁面;
不過我寫的時候感覺凌亂,不適合大家初學者學習,所以就想着要改變一下,對比了Git上的各種大神結構,偶然發現了EduardoPires的代碼,感覺很清晰,就按照他這個來了。
感謝以下文章對本系列的幫助:
1、特別鳴謝開源項目
https://github.com/EduardoPires/EquinoxProject,我基本都是在這個項目基礎上,為了廣大剛進入DDD的小伙伴的,因為直接看項目肯定看不懂。我從新建空解決方案開始,一點一點講解的,做了這個系列說明文檔,我要強調我是主要講知識,Code還是要尊重原作者,但是我的核心是布道,是對他的項目講解,因為沒有Code,我也能講知識點。
2、感謝平時遇到的特別好的文章(節選)
- 領域驅動設計,為何又死灰復燃了?
- ABP框架理論研究總結(典藏版)
- 淺談我對DDD領域驅動設計的理解
- IDDD 實現領域驅動設計-CQRS(命令查詢職責分離)和 EDA(事件驅動架構)
- 領域驅動設計的實踐 – CQRS & Event Sourcing
- CQRS Journey
3、很好的網友文章:
4、當然還有平時爭議最多的話題:
三、我的計划書中涉及到的相關知識
Bingo:這里是我的一個初步設想,以后可能根據情況進行增刪,其中很多咱們在之前的項目里都已經說到了,到時候會簡單說一下跳過,也正好溫習下,比如 WebApi的創建,依賴注入的使用,Dto數據傳輸對象的概念,Swagger 接口文檔的使用,這些大家是不是很熟悉,所以說,當時在寫上一個項目的時候,已經用了一部分DDD的思想了,現在回想起來是不是感覺自己棒棒噠。至於不懂或者沒見過的,沒關系,以后都會懂得的。
1、知識點(補充中)
- ASP.NET Core 2.1.2 👉基本框架
- ASP.NET MVC Core 👉實現mvc web頁面
- ASP.NET WebApi Core 👉實現 api 接口
- ASP.NET Identity Core 👉身份驗證
- Entity Framework Core 2.0 👉實現ORM數據持久化
- Dapper (待定)
- .NET Core 原生 DI 👉實現依賴注入
- AOP 👉面向切面
- Autofac(待定)IoC
- AutoMapper 👉實現Dtos
- FluentValidator驗證
- Swagger UI 👉實現接口文檔展示
- MediatR 👉基於內存級別的消息發布訂閱
- Azure 👉雲服務發布
2、特性(補充中)
- 領域驅動設計(Domain Driven Design (Layers and Domain Model Pattern)
- 命令查詢職責分離(CQRS:Command Query Responsibility Segregation)
- 領域通知 (Domain Notification)
- 領域驅動 (Domain Events)
- 事件驅動架構 (EDA)
- 事件回溯 (Event Sourcing)
- 最終一致性 (Eventually Consistent)
- 工作單元模式 (Unit of Work )
- 泛型倉儲 (Repository and Generic Repository)
四、開發環境與項目設想
這里再強調下,這個系列只為了說明知識點內容,可能數據很少,框架很簡單。
系統環境
windows 10、SQL server 2012、Visual Studio 2017、Windows Server 2008 R2、Linux Ubuntu、
開發環境
Visual Studio 15.3+、.NET Core SDK 2.0+、
如果順利的話,會引入下邊這些東西,如果上邊講起來很費勁,可能就順延下去了:
1、到時候肯定會有一個 WebApi 項目,如何基於這個,可以再一次搭建一個前后端分離的前端框架,至於還是 VUE,還是 Angular 6,這個再說;
2、然后會有一個 MVC 項目,很簡單,就是一個頁面的展示,主要是為了講解如何搭建 .net core MVC 項目;
3、盡量實現數據的讀寫分離;
4、實現 Dockers 的容器使用;
5、OAuth 2.0 權限等;
五、項目中的點滴
1、關於微服務
本文中,會涉及到CQRS和ES相關概念,這兩點在以后的微服務中也會有所用處,而其中關於微服務管道的總線問題,我用的是 在命令管道中使用轉存進程模式(內存中)。這種方式使用的是MediatR的中介者模式。
當然還有別人使用的另一種方式,消息隊列 RabbitMQ 或者 KafKa 等,在命令的管道中使用消息隊列(進程外)
2、本文用到的知識點樹
六、結語
本文只是簡單給大家見個面,初略說明本系列要說什么,以及DDD領域驅動設計的相關說明,還是那句話,技術是用來改善生活的,沒有一成不變的好框架,也沒有一無是處的設計思想,關鍵還是看學習者是一個什么心態罷了,江湖渺渺,各位仁兄任重而道遠呀,加油吧兄弟們~~~