領域驅動設計(DDD)思想及框架實現

定義

????????DDD是Domain driven design(領域驅動設計)的簡稱,是一種軟件設計和開發的方法論,特別適用于復雜業務領域軟件設計和開發

核心

? ??????將所有業務邏輯內聚到業務領域(domain)層,將設計和開發的關注點聚焦到業務領域

戰略上:上下文(Bounded Context)、防腐層(Anticorruption Layer)、開放主機服務

戰術上:entity\value object\Aggregate\root entity\domain service\factory\repository\domain event

????????戰略上,通過上下文(Bounded Context)解耦各個業務系統/組件,通過防腐層(Anticorruption Layer)確保各自業務領域不受外界污染,通過開放主機服務(Open Host Service)向外界提供服務。

????????戰術上,將業務對象建模為entity和value object,entity有唯一業務標識且在其生命周期中狀態可變,value object與之相反;關聯性強的entity和value object聚合成一個Aggregate,每個Aggregate有一個root entity,確保Aggregate內容業務規則和行為的一致性;業務行為盡量建模在entity/ value object 上,當業務行為無法建模到任何業務entity/value object時,可以使用領域服務(domain service);使用factory創建復雜的業務entity,使用repository實現實體的重建和持久化操作;領域相關的通知等可以通過domain event發布出去。

概念

Bounded context:邊界上下文

劃分領域邊界,邊界內領域模型保持一致,強調內聚,并與邊界外的領域模型解耦

Entity:領域實體

有唯一標識,可變的業務實體對象,有自己的生命周期,如User等

Value Object:領域值對象

沒有唯一標識,通常依附于領域實體,值對象的內容不可變 ,要么被整體替換

Aggregate:聚合

是一組業務關聯度很強的實體/值對象的集合,每個聚合都有一個根實體(root entity),通過根實體可以路由到整個聚合

Domain Event:領域事件

領域內發生的異步處理事件、異步消息通知等,比如異步寫入的登錄日志,通常借助消息隊列實現

Domain Service:領域服務

當某一類業務行為無法歸類到實體/值對象時,可以創建領域服務來完成。比如賬戶轉賬場景,涉及兩個Account實體;再比如社區敏感詞過濾場景,帖子可以用、評論也可以用,因此可以抽離到ContentFilter完成

Repository:倉庫

嚴格意義上講,倉庫是基礎設施層的東西,但為了保持領域模型的完整性,將倉庫的接口定義放到領域中,可以在領域內約束實體/值對象的行為,還可以方便地完成倉庫的內存形式實現,使得領域模型弱依賴于持久化層。這一點在書中被稱為“依賴倒置”(參考《實現領域驅動設計》P372)。

Factory:領域對象工廠

用于復雜領域對象的創建和重建,重建是指通過repository加載持久化對象后,重新創建領域對象

圖解分層

DDD分層

User Interface——用戶界面層:提供與用戶/界面交互的接口,可以是restful api,也可以是view,或者二進制形式的tcp協議接口等

Application——應用服務層:組合Domain和Infrastructure,完成具體的業務邏輯

Domain——業務領域層:是DDD中的核心層,內聚所有的業務邏輯,保持領域的一致性。需要用到Infrastructure的基礎組件

Infrastructure——基礎設施層:提供公共服務組件,比如validation、登錄態校驗、日志記錄等

架構風格

針對DDD的架構設計,《實現領域驅動設計》提到了幾種架構風格:六邊形架構、REST架構、CQRS、事件驅動等。在實際使用中,落地的架構并非是純粹其中的一種,而很有可能戶將上述幾種架構風格結合起來實現

六邊形架構

端口和適配器

DDD六邊形架構? ? ?來源于《實現領域驅動設計》

框架實現

User Interface層

門面層,對外以各種協議提供服務,該層需明確定義支持的服務協議、契約等,包括dto和controller

dto

包括request和response兩部分,定義出錯和入參的契約,可以調用基礎設施層的validation組件完成入參格式校驗

facade\controller——控制器

支持不同訪問協議的控制器實現,比如:http/restful協議、tcp協議、mq消息/json對象等,包括但不限于:

? 調用RequestMapping完成Servlet路由

? 調用checkLogin完成登錄態和權限認證

? 調用logging組件完成日志記錄

assembler——組裝器

負責將多個不同的領域對象組裝成dto對象,比如查詢帖子列表,需要從帖子(領域對象)中獲取帖子的詳情,還要從用戶(領域對象)中獲取用戶的基本信息

實現DTO與領域對象之間的相互轉換,數據交換,因此Assembler幾乎總是同DTO一起出現

不能有業務邏輯,主要負責格式轉換、字段映射等


Application層

包含service和assembler

service——應用服務層

對外,組合domain層的領域對象和基礎設施層的公共組件,根據業務需要包裝出多變的服務

? 訪問domain層的領域對象

? 訪問infrastructure的公共組件,比如消息組件等

應用服務層 訪問路線

task——邏輯任務

對內,調用領域層(領域對象或領域服務)完成各種業務邏輯任務(task)


Domain層

高內聚的業務領域層,所有的業務邏輯都在這里

domain entity——領域實體對象

有唯一標識,可變的業務實體對象,業務實體有自己的生命周期,比如社區這個業務領域中,“帖子”就是一個業務實體,它的內容和狀態可以不斷發生變化。

domain?value object——值對象

可以沒有唯一性的業務標識,通常是短暫的,與java中的值對象(基本類型和String類型)類似。比如帖子的置頂信息可以理解為一個值對象,不需要為它定義獨立的業務唯一性標識,只需要用帖子id,還有置頂狀態和置頂位置,一旦任何一個屬性值發生變化,重建值對象并賦值給帖子實體引用。

domain?factory——對象工廠

用于復雜領域對象的創建/重建。重建是指通過repository加載持久化對象后,重建領域對象

domain service——領域服務,區別與Application層的service,屬于業務領域服務

任何無法歸類給領域實體和值對象的行為,都可以為它創建獨立的領域服務,比如轉賬服務,需要操作借方/貸方兩個業務實體。傳統意義上的util類中static方法,涉及業務邏輯的,都可以歸入domain service

domain event——領域事件

領域中一些消息事件,通過事件通知和訂閱的方式,可以在性能和解耦方面提供非常大的好處

repository——倉庫

與domain entity緊密聯系,通過與基礎設施的持久化層交互后 ,完成領域對應的增刪改查操作

根據不同業務場景,倉庫的實現,可以是reids、數據庫、mongodb等

translator(翻譯器,一般可以沒有這一層)

將持久化的對象翻譯成統一領域對象,不應該有業務邏輯,負責格式轉換、字段映射等。

作用等同于Application層中的轉換器 assembler

Infrastructure層

公共基礎組件,供User Interface中的controller、Application層中的service、以及整個Domain層調用

repository impl?

對domain層repository接口的實現,對應每種存儲介質有其特定實現,如oracle的mapper,mongodb的dao等等。repository impl會調用mybatis、mongo client、redis client完成實際的存儲層操作。

authorization 權限認證

提供給User Interface層的Controller調用。

exception 異常處理

提供公共的異常處理邏輯

logging 日志記錄

日志模塊

transport 傳輸器

transport完成和第三方服務的交互,可以有多種協議形式的實現,如http+json、tcp+自定義協議等,配套使用的還有Resolver解析器,用于對第三方服務的請求和響應進行適配,提供一個防腐層(AnticorruptionLayer)的作用

transaction 事務管理

事務管理,一般交給Spring管理

DDD的框架實現示意圖

DDD的框架實現


轉載自:https://www.cnblogs.com/daoqidelv/p/7492322.html?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379