大話領域驅動設計——領域層

概述

在DDD中,業務邏輯主要分布在領域層和應用層兩層,他們包含不同的業務邏輯。這一篇,我們先對領域層做詳細的講解分析。

f6864ef0a47e96f3326bfafe676d51f3.png

領域層實現了領域或系統的,與用戶界面上的用戶交互(用例)無關的核心業務邏輯。

總覽

a1f6bc9eb20d813a9ff095f5964beadd.png

領域層主要包含以下組件:

實體(Entity)實體是一個具有自己的屬性(狀態、數據)和實現在這些屬性上執行的業務邏輯的方法的對象。實體由其唯一標識符(Id)表示。具有不同id的兩個實體對象被視為不同的實體。

聚合和聚合根Aggregate&Aggregate Root聚合是通過集合根對象綁定在一起的對象集(實體和值對象)。聚合根是具有一些附加職責的實體的特定類型。

值對象Value Object值對象是另一種由其屬性而不是唯一的Id來標識的域對象。這意味著兩個具有相同屬性的值對象將被視為相同的對象。值對象通常被實現為不可變對象,而且大多數值對象都比實體要簡單得多。

域服務Domain Service領域服務是一個實現域的核心業務規則的無狀態服務。它依賴于多個聚合(實體)類型或某些外部服務,用于領域邏輯的實現。

倉儲Repository接口:倉儲是一個類似于集合的接口,它被領域層和應用層用于訪問數據持久化系統(數據庫)。它對業務代碼隱藏了DBMS的復雜性。領域層包含倉儲的接口聲明。

規約(Specification)規約用于為實體和其他業務對象定義已命名的、可重用的且可組合的過濾器。

域事件Domain Event領域事件是在領域特定事件發生時以松散耦合的形式通知其他服務的一種方法。

6989b5c66bdf94194dfce671608df44c.png

在ABP框架下,領域層包含以下兩個項目:

Domain是包含所有組件(實體、聚合根、值對象、領域服務、規約、存儲庫接口等)的基本領域層。?

Domain.Shared是一個輕量的項目,它包含了屬于領域層的一些類型,但與所有其他層共享。例如,它可能包含一些與域對象相關的常量和枚舉,但需要被其他層重用。

實現細節

1

實體

d99bf0154481c8f78eeb25695586bb10.gif

在ABP中,所有的實體類均需實現ABP框架中定義的接口?IEntity?。ABP中將實體分為兩種用法:有默認主鍵(Id)的實體和沒有默認主鍵的實體。

dcdd060a5667d54cc176a6a617091172.gif

有默認主鍵的實體在?IEntity?接口基礎上封裝了?IEntity<TKey>?接口,其中,定義了TKey類型的主鍵,名稱為Id。其默認實現類繼承自?Entity<TKey>?。我們使用時,需以泛型方式定義主鍵的類型。

ecfe3141412cdaa5461b99f19d87432d.gif

無默認主鍵的實體類直接實現IEntity接口,其默認實現類繼承自?Entity?,在?Entity?中定義了虛方法?object[] GetKeys()?。該方法用于設定一個或多個屬性為主鍵。使用無默認主鍵的實體時,我們必須實現GetKeys方法指定該實體類對應數據庫表的主鍵。

0f5d30de4891cbc2dfc16c17e370159d.gif

在ABP中,對于實體定義了默認增刪改操作的審計屬性,通過?ICreationAuditedObject?,?IModificationAuditedObject?和?IDeletionAuditedObject?三個接口進行約束,分別包含對添加(添加人,添加時間),修改(修改人、修改時間),刪除(刪除人、刪除時間、是否被軟刪除)操作記錄的審計屬性。ABP為ICreationAuditedObject接口創建了默認實現基類?CreationAuditedEntity?,同時還創建了包含以上三個接口所有實現的基類?FullAuditedEntity?,?CreationAuditedEntity?和?FullAuditedEntity?均包含有默認主鍵和無默認主鍵兩種用法,以是否定義泛型來區分。

db11c5c0a0283e6c1265fa1fe4f9c364.gif

ABP中定義了?ISoftDelete?接口,其中包含?IsDeleted?屬性,表示該條數據是否被軟刪除。當實體實現ISoftDelete接口時,ABP的倉儲會自動將刪除方法轉為軟刪除,即只將IsDeleted屬性設置為true,使其部不被查詢到,但并不在數據庫中對數據進行物理刪除。

2

聚合根

b75a868ee3b7b17082a949e48dba0b60.gif

在ABP中聚合根需實現I?AggregateRoot?,其默認基類為?AggregateRoot?,同時?AggregateRoot?也實現了?IEntity?接口。?IAggregateRoot?本身未包含任何屬性或者方法的聲明,其主鍵聲明繼承自IEntity接口。

3317f3645d7b31d145de429e82a5f413.gif

和實體類相同,聚合根也定義了有默認主鍵和無默認主鍵兩種用法,通過是否傳入泛型來進行區分。

22d1d1076000390e2e2a27d07d41efa9.gif

聚合根也可以實現?ICreationAuditedObject?, ?IModificationAuditedObject?和?IDeletionAuditedObject?對增刪改操作進行審計記錄,其中實現接口?ICreationAuditedObject?的基類為?CreationAuditedAggregateRoot?,實現所有審計接口的基類為?FullAuditedEntity?。

3

值對象

501c04870e9f83d37a48fd8014e69584.gif

值對象的定義相對來說非常簡單,在ABP中,定義了值對象的基類 ?ValueObject??,定義值對象必須繼承ValueObject??ValueObject?并實現ValueObject中定義的抽象方法?GetAtomicValues()?。

4e05c32f8fa526dd4c20e813f31d6bbb.gif

GetAtomicValues?方法用于檢查兩個值對象是否相等,其用法為通過?yield?return?返回一組屬性,表示如果兩個值對象這些屬性值都相等,則這兩個為相等的值對象。示例代碼如下:

protected override IEnumerable<object> GetAtomicValues() { ? ?yield return Street; ? ?yield return CityId; ? ?yield return Number; }

4

領域服務

c7d26fd7796c8b664a6797caf1a19e81.gif

領域服務的接口和實現均包含在領域層Domain項目中,其中領域服務接口聲明繼承自ABP提供的?IDomainService?接口,領域服務實現類繼承自ABP提供的?DomainService?類。

705f7cbbdd6e000118383cc61718b416.gif

在?IDomainService?接口中未聲明任何屬性和方法,我們如果需要用到領域服務,可完全依據自己的需求定義其中的內容。

2ae9b1ec76f42bffa1678baae0e09202.gif

在ABP框架中,領域服務通過自動依賴注入的方式以瞬態生命周期被注冊到IOC容器中,即每次使用都會生成一個新的實例。我們只需要保證其所在類庫中含有繼承自?AbpModule?的模塊定義類,即可實現自動依賴注入。

5

倉儲接口

bfc18922adedee800ab47b2e81ff5d27.gif

在領域層Domain項目中,只會聲明倉儲的接口,其實現需要在基礎設施層的EntityFrameworkCore項目中編寫。

adccfb30240008174b9760243dab2780.gif

ABP框架已經為我們提供了默認的倉儲接口和實現,在大多數情況下,我們不需要編寫任何倉儲接口或實現類的代碼,只需要在使用時注入?IRepository<TEntity, TKey>?,其中的兩個泛型分別為實體/聚合根的類型和主鍵數據類型。

b703a67b9f718b113d156c8550142d98.gif

如果我們需要自定義倉儲,則在Domain層定義其接口聲明,倉儲接口聲明需要繼承自?IRepository?接口。

6

規約

5c60c9487a3eadfa28d60e0eddc1d23d.gif

ABP提供了規約的接口?ISpecification<T>?和實現類基類?Specification<T>?,其中泛型為需要約束的實體或聚合根的類型。

c1e533cec5d579169754b45a2c76760e.gif

編寫規約時必須實現?ISpecification?接口中定義的?ToExpression?方法,該方法用來聲明規約中數據約束的表達式。

04df26045f39a23d0a52f8dd82700635.gif

同時,?ISpecification?接口中還定義了?IsSatisfiedBy?方法,用于判斷一個對象是否滿足此規約,在?Specification?類中已提供了此方法的默認實現。

7

領域事件

9c69ff32d4e7d3d1ce38169c4f438be2.gif

ABP提供了本地事件總線和分布式事件總線兩種方案,其中本地事件總線常用于我們DDD中傳統意義的領域事件實現,而分布式事件總線常用于分布式或微服務系統的事件處理。

299ae0b53aede7759bd17afda4e49d4a.gif

ABP本地領域事件使用主要分為訂閱和發布兩個部分:

ef875f76f79d2234b817762668382a4b.gif

發布和訂閱的事件或對應關系以其傳輸的數據類型為區分。對于每種事件,我們都需要單獨定義一個事件類型的簡單類(ABP未提供統一基類,直接繼承自Object即可)用于存放傳輸的數據,即使不需要傳輸數據,我們也要定義一個空類來區分事件類型。該類型命名通常以Event結尾。

84be11402024ce1957cc5855a78f940b.gif

在DomainService、ApplicationService、Controller等可以使用依賴注入的組件中,我們可以注入?ILocalEventBus?接口并調用?PublishAsync?方法來發布事件,在Entity和Aggregate Root中無法使用依賴注入,ABP官方給他們提供了一個基礎方法?AddLocalEvent?用于發布事件。

561425a67114551a8e5f7d44fdbfeb46.gif

在訂閱事件時我們需要定義一個類,實現?ILocalEventHandler<T>??其中的泛型為前面所說的事件類型定義,并實現接口中的?HandleEventAsync?方法用于處理事件。

END

a7c4beee43dd6df1e2230a10f670fa11.png

625dc2c371b6ba58539c75465dd25fd2.png

關注我獲得

更多精彩

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/286822.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/286822.shtml
英文地址,請注明出處:http://en.pswp.cn/news/286822.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【北斗】北斗衛星導航系統(BDS)介紹

一、概述 北斗衛星導航系統(以下簡稱北斗系統)是中國著眼于國家安全和經濟社會發展需要,自主建設運行的全球衛星導航系統,是為全球用戶提供全天候、全天時、高精度的定位、導航和授時服務的國家重要時空基礎設施。 北斗系統提供服務以來,已在交通運輸、農林漁業、水文監…

Android之解決VideoView控件的進度條位置擺放問題和打開播放黑屏問題

1 問題 VideoView控件如何配合MediaController使用,就會顯示進度條,但是位置擺放在最底部,不是我們想要的結果 2、基本使用 private var mMediaController:MediaController? = nullfun playVedio() {mMediaController = MediaController(this as Activity)trashVideoView…

Snmp linux

http://blog.csdn.net/youngqj/article/details/7311849 http://blog.csdn.net/howema/article/details/4182408 http://my.oschina.net/yisenn/blog/14626轉載于:https://www.cnblogs.com/diyunpeng/p/5720952.html

正則驗證金額大于等于0,并且只到小數點后2位

2019獨角獸企業重金招聘Python工程師標準>>> ^(([0-9]|([1-9][0-9]{0,9}))((\.[0-9]{1,2})?))$ 轉載于:https://my.oschina.net/u/934148/blog/528688

我結婚了,我要用什么做個邀請函呢?【iVX無代碼YYDS 06】

作者簡介 作者名&#xff1a;1_bit 簡介&#xff1a;CSDN博客專家&#xff0c;2020年博客之星TOP5&#xff0c;InfoQ簽約作者、CSDN新星導師&#xff0c;華為云享專家。15-16年曾在網上直播&#xff0c;帶領一批程序小白走上程序員之路。歡迎各位小白加我咨詢我相關信息&#…

【專升本計算機】計算機文化基礎練習題(選擇題300道附答案)

專升本計算機文化基礎練習題 1、 世界上第一臺電子計算機誕生于 ______A_ 。 A . 20 世紀 40 年代 B . 19 世紀 C . 20 世紀 80 年代 D . 1950 年 2、 世界上第一臺電子計算機是 1946 年在美國研制成功的,該機的英文縮寫名是 ___A__ 。 A . ENIAC B . EDVAC C…

《微軟云計算Microsoft Azure部署與管理指南》即將上市!!!

大家好&#xff0c;本人新作《微軟云計算Microsoft Azure部署與管理指南》即將與廣大讀者見面&#xff0c;由電子工業出版社出版。希望大家能關注此書&#xff0c;并推薦給身邊的好友和技術人員。 眾所周知&#xff0c;Microsoft Azure是專業的國際化公有云平臺, 是微軟研發的公…

如何用SQL來檢測文件是否存在

工作中&#xff0c;我們經常需要檢查上傳的文件是否存在&#xff0c;用戶上傳的頭像是否存在&#xff0c;等等。 有沒有辦法直接用SQL來查詢呢&#xff1f; 請直接看代碼&#xff1a; /************************************************************ * Create By Jacky * T…

如何解決分布式日志exceptionless的寫入瓶頸

我們都知道在分布式日志當中&#xff0c;exceptionless客戶端是把日志寫到Elasticsearch數據庫&#xff0c;就像我們把數據寫入到關系數據庫一樣&#xff1b;既然是寫入&#xff0c;那么在短時間大數據量的情況下&#xff0c;寫入就會涉及到效率的問題&#xff1b;首先我們看下…

iVX 基礎

1.1 iVX 線上集成環境進入 點擊 連接 或通過瀏覽器輸入網址 https://editor.ivx.cn/ 進入線上集成開發環境。 進入 在線集成開發環境 后&#xff0c;可點擊右上角 登錄/注冊 進行帳號登錄或者注冊。登錄賬戶 后在進行項目開發時會自動保存項目開發進度。 [外鏈圖片轉存失敗…

關于有序二維矩陣查找和字符串替換的兩道算法題

最近看一本書上寫到的兩個面試題 于是實現了一下 感覺思路很好,大牛略過 : 1、對于一個二維矩陣,從左到右 從上到下 都是遞增的,如何判斷一個值是否在矩陣內部?&#xff08;C實現 實現復雜度 O(n)&#xff09; bool FindInTwoDimensionalMatrix(int*pMatrix,int iRows,int i…

Maven實戰:pom.xml與settings.xml

pom.xml與settings.xml pom.xml與setting.xml&#xff0c;可以說是Maven中最重要的兩個配置文件&#xff0c;決定了Maven的核心功能&#xff0c;雖然之前的文章零零碎碎有提到過pom.xml和settings.xml里面的內容&#xff0c;但都是大略帶過&#xff0c;學習與研究地并不細致&am…

Android之靠譜的把圖片和視頻插入手機系統相冊

1 需求 把圖片和視頻插入手機系統相冊,網上查了下基本上很亂,沒幾個靠譜的。 2 結果爆照 3 思路 圖片插入系統相冊(可以直接插入系統相冊,但是我這里多做了一步就是先把圖片拷貝到了一個目錄再插入系統相冊) 視頻插入系統相冊(先把視頻拷貝到MIUI目錄,然后再…

【專升本計算機】計算機操作系統練習題(選擇判斷名詞解釋簡答)

一、填空 1. 操作系統為用戶提供三種類型的使用接口,它們是 命令方式 和 系統調用 和 圖形用戶界面 。 2. 主存儲器與外圍設備之間的數據傳送控制方式 ( I/O 控制方式) 有 程序直接控制、中斷驅動方式、 DMA 方式 和 通道控制方式。 3. 在響應比最高者優先的作業調…

C# WPF 實現Tab頁動態增減

概述Tab頁面是一個很常用的控件&#xff0c;針對頁面固定的場景&#xff0c;直接給Item進行數據綁定就行&#xff0c;如下所示&#xff1a;<dx:DXTabControl cal:Message.Attach"[Event Loaded][TabControl_Loaded($source,$eventArgs)]"><dx:DXTabItem Hea…

2014 網選 上海賽區 hdu 5047 Sawtooth

題意&#xff1a;求n個M型的折線將一個平面分成的最多的面數&#xff01; 思路&#xff1a;我們都知道n條直線將一個平面分成的最多平面數是 An An-1 n1 也就是f(n) (n*n n 2)/2 對于一個M型的折線呢&#xff1f;它有四條線&#xff0c;但是由于三個頂點的關系導致劃分的平…

二、基礎(IVX快速開發手冊)

二、基礎 通過本節你將了解 iVX 所支持應用的創建方法。 文章目錄二、基礎2.1 iVX 線上集成環境進入2.2 創建項目2.3 選擇項目類型2.3.1 WebApp/小程序/原生應用2.3.2 微信小游戲2.3.3 微信小程序&#xff08;原生組件&#xff09;2.1 iVX 線上集成環境進入 點擊 連接 或通過…

【專升本計算機】經典Office 2003專升本復習題(Word、Excel、PowerPoint)

經典Office 2003專升本復習題(Word、Excel、PowerPoint) 一、Word 2003 1. 啟動 Word 是指: 將 Word 從硬盤中調入主存執行 2. 菜單欄: 文件( F )、編輯( E )、視圖( V )、插入( I )、格式( O )、工具( T )、表格( A )、窗口( W )、幫主( H ) 3. …

Android之TabLayout+ViewPager2+FragmentStateAdapter實現帶數字變化的TAB選項

1 問題 TabLayout+ViewPager2實現帶數字變化的TAB選項,然后左邊滑動或者點擊上面的Tab切換fragment不能刷新 2 結果爆照 3 代碼實現 layer_tab_indicator.xml <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="h…

slq2000數據庫升級到sql2012

看到標題&#xff0c;估計有同行笑了&#xff0c;這年代還有用sql2000的&#xff1f;真的有&#xff0c;最近單位服務器數據遷移升級&#xff0c;將數據庫遷移到新服務器后&#xff0c;發現數據全是2000的&#xff0c;無法直接導入到sql2012。沒辦法&#xff0c;只能先將數據庫…