成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

DDD 是什么?—— 你以前只會用 Service + 貧血模型!

開發 前端
在 DDD 中,每一個領域都是界限上下文拆分的獨立結果,而實現業務流程的功能則需要串聯各個領域模塊提供一整條鏈路的完整服務。所以也常說領域內事務一致性,領域外最終一致性。

大家好,我是技術UP主小傅哥。

DDD 是什么,這應該是每個想使用 DDD 開發項目的研發伙伴,遇到的第一個疑問,只有搞清楚它到底是什么才好上手使用。而 DDD 既不是 MVC 一樣的工程結構,也不能直接等同于微服務架構,更不是一種設計模式。

1. DDD 是什么

那 DDD 是什么呢?來自于維基百科的一段定義:"Domain-driven design (DDD) is a major software design approach. ",DDD 是一種軟件設計方法。也就是說 DDD 是指導我們做軟件工程設計的一種手段,它提供了用切割工程模型的各類技巧,如;領域、界限上下文、實體、值對象、聚合、工廠、倉儲等。通過 DDD 的指導思想,我們可以在前期投入更多的時間,更加合理的規劃出可持續迭代的工程設計。

在 DDD 中有一套共識的工程兩階段設計手段,包括;戰略設計、戰術設計。

  • 戰略設計,主要以應對復雜的業務需求,通過抽象、分治的過程,合理的拆分為獨立的多個微服務,從而分而治之。與之評價拆分的是否合理,則是在需求開發上線時候,是否每次都大量操作多個微服務開發和上線。這樣的戰略設計是一種失敗的微服務單體設計。所以少數幾個中等規模的單體應用,周圍環繞著一個服務生態系統,這更有意義。你實際上并沒有構建微服務 @賈斯汀·埃瑟里奇
  • 戰術設計,在這個范疇下,主要以討論如何基于面向對象思維,運用領域模型來表達業務概念。通常在不做領域模型設計的架構,也就是通常映射到 MVC 三層架構下,Service + 數據模型的開發模式,會讓 Service 扁平的、大量的,平鋪出非常復雜的業務邏輯代碼。再加上行為對象與功能邏輯的分離,貧血模型的開發方式,讓行為對象的不斷交叉使用,也是讓系統不斷增加復雜度,并到難以維護的根因。所以這一階段要設計每一個可以表達領域概念的模型,并運用實體、聚合、領域服務來承載。

2. DDD 的概念

什么是充血模型,領域內都包括什么,實體、聚合、值對象,有什么區別?這樣一些"為什么"的概念,也是戰術設計過程中非常重要的知識項。搞清楚它們才能做 DDD 設計。

2.1 充血模型

充血模型,指將對象的屬性信息與行為邏輯聚合到一個類中,常用的手段如在對象內提供屬于當前對象的信息校驗、拼裝緩存Key、不含服務接口調用的邏輯處理等。

圖片圖片

  • 這樣的方式可以在使用一個對象時,就順便拿到這個對象的提供的一系列方法信息,所有使用對象的邏輯方法,都不需要自己再次處理同類邏輯。
  • 但不要只是把充血模型,僅限于一個類的設計和一個類內的方法設計。充血還可以是整個包結構,一個包下包括了用于實現此包 Service 服務所需的各類零部件(模型、倉儲、工廠),也可以被看做充血模型。
  • 同時我們還會再一個同類的類下,提供對應的內部類,如用戶實名,包括了,通信類、實名卡、銀行卡、四要素等。它們都被寫進到一個用戶類下的內部子類,這樣在代碼編寫中也會清晰的看到子類的所屬信息,更容易理解代碼邏輯,也便于維護迭代。

2.2 領域模型

領域模型,指特定業務領域內,業務規則、策略以及業務流程的抽象和封裝。在設計手段上,通過風暴模型拆分領域模塊,形成界限上下文。最大的區別在于把原有的眾多 Service + 數據模型的方式,拆分為獨立的有邊界的領域模塊。每個領域內創建自身所屬的;領域對象(實體、聚合、值對象)、倉儲服務(DAO 操作)、工廠、端口適配器Port(調用外部接口的手段)等。

那么,現在這里有幾個概念;領域服務、領域對象、倉儲定義、事件消息、端口適配器。我們先來看他們是怎么從貧血模型演變過來的,在細分講解每個概念。

圖片圖片

  • 在原本的 Service + 貧血的數據模型開發指導下,Service 串聯調用每一個功能模塊。這些基礎設施(對象、方法、接口)是被相互掉調用的。這也是因為貧血模型并沒有面向對象的設計,所有的需求開發只有詳細設計。
  • 換到充血模型下,現在我們以一個領域功能為聚合,拆分一個領域內所需的 Service 為領域服務,VO、Req、Res 重新設計為領域對象,DAO、Redis 等持久化操作為倉儲等。舉例;一套賬戶服務中的,授信認證、開戶、提額降額等,每一個都是一個獨立的領域,在每個獨立的領域內,創建自身領域所需的各項信息。
  • 領域模型還有一個特點,它自身只關注業務功能實現,不與外部任何接口和服務直連。如;不會直接調用 DAO 操作庫,也不會調用緩存操作 Redis,更不會直接引入 RPC 連接其他微服務。而是通過倉庫和端口適配器,定義調用外部數據的含有出入參對象的接口標準,讓基礎設施層做具體的調用實現。通過這樣的方式讓領域只關心業務實現,同時做好防腐。

2.3 實體、聚合、值對象

原本在貧血模型下的開發,常常是不會特別在意一個方法的出入參對象的,也經常是很多個服務共用一個VO對象作為入參,只要這個對象能把我需要的屬性信息帶進來就可以了。

但在 DDD 的領域模型設計下,領域對象的設計是非常面向對象的。而且在整個風暴事件的四色建模過程也是在以領域對象為驅動進行的。

實體、聚合、值對象,三者位于每個領域下的領域對象內,服務于領域內的領域服務。三個對象定義具體如下;

圖片圖片

實體

是依托于持久化層數據以領域服務功能目標為指導設計的領域對象。持久化PO對象是原子類對象,不具有業務語義,而實體對象是具有業務語義且有唯一標識的對象,跟隨于領域服務方法的全生命周期對象。如;用戶PO持久化對象,會涵蓋,用戶的開戶實體、授信實體、額度實體對象。也包括如商品下單時候的購物車實體對象。這個對象也通常是領域服務方法的入參對象。

  • 概念:實體 = 唯一標識 + 狀態屬性 + 行為動作(功能),是DDD中的一個基本構建塊,它代表了具有唯一標識的領域對象。實體不僅僅包含數據(狀態屬性),還包含了相關的行為(功能),并且它的標識在整個生命周期中保持不變。
  • 特征:

唯一標識:實體具有一個可以區分其他實體的標識符。這個標識符可以是一個ID、一個復合鍵或者是一個自然鍵,關鍵是它能夠唯一地標識實體實例。

領域標識:實體的標識通常來源于業務領域,例如用戶ID、訂單ID等。這些標識符在業務上有特定的含義,并且在系統中是唯一的。

委派標識:在某些情況下,實體的標識可能是由ORM(對象關系映射)框架自動生成的,如數據庫中的自增主鍵。這種標識符雖然可以唯一標識實體,但它并不直接來源于業務領域。

  • 用途:
  • 表達業務概念:實體用于在軟件中表達具體的業務概念,如用戶、訂單、交易等。通過實體的屬性和行為,可以描述這些業務對象的特征和能力。

  • 封裝業務邏輯:實體不僅僅承載數據,還封裝了業務規則和邏輯。這些邏輯包括驗證數據的有效性、執行業務規則、計算屬性值等。這樣做的目的是保證業務邏輯的集中和一致性。

  • 保持數據一致性:實體負責維護自身的狀態和數據一致性。它確保自己的屬性和關聯關系在任何時候都是正確和完整的,從而避免數據的不一致性。

  • 實現手段:

  • 定義實體類:在代碼中定義一個類,該類包含實體的屬性、構造函數、方法等。

  • 實現唯一標識:為實體類提供一個唯一標識的屬性,如ID,并確保在實體的生命周期中這個標識保持不變。

  • 封裝行為:在實體類中實現業務邏輯的方法,這些方法可以操作實體的狀態,并執行相關的業務規則。

  • 使用ORM框架:利用ORM框架將實體映射到數據庫表中,這樣可以簡化數據持久化的操作。

  • 實現領域服務:對于跨實體或跨聚合的操作,可以實現領域服務來處理這些操作,而不是在實體中直接實現。

  • 使用領域事件:當實體的狀態發生變化時,可以發布領域事件,這樣可以通知其他部分的系統進行相應的處理。

值對象

這個對象在領域服務方法的生命周期過程內是不可變對象,也沒有唯一標識。它通常是配合實體對象使用。如為實體對象提供對象屬性值的描述,比如;一個公司雇員的級別值對象,一個下單的商品收貨的四級地址信息對象。所以在開發值對象的時候,通常不會提供 setter 方法,而是提供構造函數或者 Builder 方法來實例化對象。這個對象通常不會獨立作為方法的入參對象,但做可以獨立作為出參對象使用。

  • 概念:值對象是由一組屬性組成的,它們共同描述了一個領域概念。與實體(Entity)不同,值對象不需要有一個唯一的標識符來區分它們。值對象通常是不可變的,這意味著一旦創建,它們的狀態就不應該改變。
  • 特征:

不可變性(Immutability):值對象一旦被創建,它的狀態就不應該發生變化。這有助于保證領域模型的一致性和線程安全性。

等價性(Equality):值對象的等價性不是基于身份或引用,而是基于對象的屬性值。如果兩個值對象的所有屬性值都相等,那么這兩個對象就被認為是等價的。

替換性(Replaceability):由于值對象是不可變的,任何需要改變值對象的操作都會導致創建一個新的值對象實例,而不是修改現有的實例。

側重于描述事物的狀態:值對象通常用來描述事物的狀態,而不是事物的唯一身份。

可復用性(Reusability):值對象可以在不同的領域實體或其他值對象中重復使用。

  • 用途:
  • 金額和貨幣(如價格、工資、費用等)

  • 度量和數據(如重量、長度、體積等)

  • 范圍或區間(如日期范圍、溫度區間等)

  • 復雜的數學模型(如坐標、向量等)

  • 任何其他需要封裝的屬性集合

  • 實現手段:

  • 定義不可變類:確保類的所有屬性都是私有的,并且只能通過構造函數來設置。

  • 重寫equals和hashCode方法:這樣可以確保值對象的等價性是基于它們的屬性值,而不是對象的引用。

  • 提供只讀訪問器:只提供獲取屬性值的方法,不提供修改屬性值的方法。

  • 使用工廠方法或構造函數創建實例:這有助于確保值對象的有效性和一致性。

  • 考慮序列化支持:如果值對象需要在網絡上傳輸或存儲到數據庫中,需要提供序列化和反序列化的支持。

聚合

當你對數據庫的操作需要使用到多個實體時,可以創建聚合對象。一個聚合對象,代表著一個數據庫事務,具有事務一致性。聚合中的實體可以由聚合提供創建操作,實體也被稱為聚合根對象。一個訂單的聚合,會涵蓋;下單用戶實體對象、訂單實體、訂單明細實體和訂單收貨四級地址值對象。而那個作為入參的購物車實體對象,已經被轉換為實體對象了。—— 聚合內事務一致性,聚合外最終一致性。

  • 概念:聚合是領域模型中的一個關鍵概念,它是一組具有內聚性的相關對象的集合,這些對象一起工作以執行某些業務規則或操作。聚合定義了一組對象的邊界,這些對象可以被視為一個單一的單元進行處理。
  • 特征:

一致性邊界:聚合確保其內部對象的狀態變化是一致的。當對聚合內的對象進行操作時,這些操作必須保持聚合內所有對象的一致性。

根實體:每個聚合都有一個根實體(Aggregate Root),它是聚合的入口點。根實體擁有一個全局唯一的標識符,其他對象通過根實體與聚合交互。

事務邊界:聚合也定義了事務的邊界。在聚合內部,所有的變更操作應該是原子的,即它們要么全部成功,要么全部失敗,以此來保證數據的一致性。

  • 用途:
  1. 封裝業務邏輯:聚合通過將相關的對象和操作封裝在一起,提供了一個清晰的業務邏輯模型,有助于業務規則的實施和維護。

  2. 保證一致性:聚合確保內部狀態的一致性,通過定義清晰的邊界和規則,聚合可以在內部強制執行業務規則,從而保證數據的一致性。

  3. 簡化復雜性:聚合通過組織相關的對象,簡化了領域模型的復雜性。這有助于開發者更好地理解和擴展系統。

  • 實現手段:

  • 定義聚合根:選擇合適的聚合根是實現聚合的第一步。聚合根應該是能夠代表整個聚合的實體,并且擁有唯一標識。

  • 限制訪問路徑:只能通過聚合根來修改聚合內的對象,不允許直接修改聚合內部對象的狀態,以此來維護邊界和一致性。

  • 設計事務策略:在聚合內部實現事務一致性,確保操作要么全部完成,要么全部回滾。對于聚合之間的交互,可以采用領域事件或其他機制來實現最終一致性。

  • 封裝業務規則:在聚合內部實現業務規則和邏輯,確保所有的業務操作都遵循這些規則。

  • 持久化:聚合根通常與數據持久化層交互,以保存聚合的狀態。這通常涉及到對象-關系映射(ORM)或其他數據映射技術。

2.4 倉儲和適配器

在 DDD 的設計方法中,領域層做到了只關心領域服務實現。最能體現這樣設計的就是倉庫和適配器的設計。通常在 Service + 數據模型的設計中,會在 Service 中引入 Redis、RPC、配置中心等各類其他外部服務。但在 DDD 中,通過倉儲和適配器以及基礎設施層的定義,解耦了這部分內容。

圖片圖片

  • 特征:

封裝持久化操作:Repository負責封裝所有與數據源交互的操作,如創建、讀取、更新和刪除(CRUD)操作。這樣,領域層的代碼就可以避免直接處理數據庫或其他存儲機制的復雜性。

領域對象的集合管理:Repository通常被視為領域對象的集合,提供了查詢和過濾這些對象的方法,使得領域對象的獲取和管理更加方便。

抽象接口:Repository定義了一個與持久化機制無關的接口,這使得領域層的代碼可以在不同的持久化機制之間切換,而不需要修改業務邏輯。

  • 用途:
  • 數據訪問抽象:Repository為領域層提供了一個清晰的數據訪問接口,使得領域對象可以專注于業務邏輯的實現,而不是數據訪問的細節。

  • 領域對象的查詢和管理:Repository使得對領域對象的查詢和管理變得更加方便和靈活,支持復雜的查詢邏輯。

  • 領域邏輯與數據存儲分離:通過Repository模式,領域邏輯與數據存儲邏輯分離,提高了領域模型的純粹性和可測試性。

  • 優化數據訪問:Repository實現可以包含數據訪問的優化策略,如緩存、批處理操作等,以提高應用程序的性能。

  • 實現手段:

  • 定義Repository接口:在領域層定義一個或多個Repository接口,這些接口聲明了所需的數據訪問方法。

  • 實現Repository接口:在基礎設施層或數據訪問層實現這些接口,具體實現可能是使用ORM(對象關系映射)框架,如MyBatis、Hibernate等,或者直接使用數據庫訪問API,如JDBC等。

  • 依賴注入:在應用程序中使用依賴注入(DI)來將具體的Repository實現注入到需要它們的領域服務或應用服務中。這樣做可以進一步解耦領域層和數據訪問層,同時也便于單元測試。

  • 使用規范模式(Specification Pattern):有時候,為了構建復雜的查詢,可以結合使用規范模式,這是一種允許將業務規則封裝為單獨的業務邏輯單元的模式,這些單元可以被Repository用來構建查詢。

Repository模式是DDD(領域驅動設計)中的一個核心概念,它有助于保持領域模型的聚焦和清晰,同時提供了靈活、可測試和可維護的數據訪問策略。

倉儲解耦的手段使用了依賴倒置的設計,所有領域需要的外部服務,不在直接引入外部的服務,而是通過定義接口的方式,讓基礎設施層實現領域層接口(倉儲/適配器)的方式來處理。

那么也就是基礎設置層負責原則對接數據庫、緩存、配置中心、RPC接口、HTTP接口、MQ推送等各項資源,并承接領域服務的接口調用各項服務為領域層提供數據能力。

同時這也會體現出,領域層的實現是具有業務語義的,而到了基礎設置層則沒有業務語義,都是原子的方法。通過原子方法的組合為領域業務語義提供支撐。

2.5 領域編排

在 DDD 中,每一個領域都是界限上下文拆分的獨立結果,而實現業務流程的功能則需要串聯各個領域模塊提供一整條鏈路的完整服務。所以也常說領域內事務一致性,領域外最終一致性。

同時這些領域模塊因為是獨立的,所以也可以被復用。在不同的場景功能訴求下,可以選擇不同的領域模塊進行組裝,這個過程就像搭積木一樣。

但這里有一個取舍,如果項目相對來說并不大,也沒有太多的編排處理。那么可以直接讓觸發器層對接領域層,減少編排層后,編碼會更加便捷。

2.6 觸發器

在所有的模型都定義完成后,領域業務被串聯了。那么接下來則是使用,而使用的方式可以包括;接口(http/rpc)、消息監聽、定時任務等方式,這些方式統一被定義為觸發動作。

由觸發發起對編排功能的調用處理。如;定時任務做信貸的計息、開戶成功消息通知返利優惠券、提供接口讓外部調用授信邏輯等。這些都是觸發動作。

責任編輯:武曉燕 來源: bugstack蟲洞棧
相關推薦

2022-04-28 21:53:52

TypeScriptany類型

2021-11-30 10:38:09

splitStringTokenJava

2022-02-16 09:29:06

領域模型貧血模型充血模型

2022-11-07 17:50:36

2020-03-06 10:25:10

注解Java代碼

2021-09-15 16:05:41

map.putJavaMap

2021-03-16 15:12:57

CompletableFuture機制java

2021-02-02 09:37:20

CQRS系統數據庫

2023-07-04 07:53:53

MVCDDD架構

2021-05-06 05:30:33

JSONstringify()parse()

2012-07-03 16:56:12

Hadoop

2025-01-26 10:10:30

2013-10-23 10:51:48

開發模型軟件開發軟件產業

2022-11-30 08:27:26

微服務設計服務

2025-05-28 03:00:00

2016-05-04 10:36:42

iossdwebimage開發

2023-01-10 08:43:15

定義DDD架構

2009-09-17 18:40:12

CLR是什么

2021-09-26 05:41:13

數字困境IT領導數字轉型

2009-11-05 09:29:29

WCF是什么
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九热在线免费视频 | 国产98色在线 | 日韩 | 成人国产一区二区三区精品麻豆 | 福利在线观看 | 亚洲精品免费观看 | 欧美精品在线播放 | 99国产精品久久久 | 国产精品夜间视频香蕉 | 九九久久在线看 | 成人午夜在线 | 人人玩人人添人人澡欧美 | 日韩h| 一区二区三区四区电影视频在线观看 | 一区二区三区在线电影 | 青春草国产 | 男女av| 成人三区 | 免费看a | 亚洲少妇综合网 | 亚洲欧美一区二区三区视频 | 欧美日韩一区二区三区四区五区 | 欧美精品一区二区在线观看 | 国产精品综合网 | 欧美99 | 一区二区三区日 | 99精品欧美一区二区三区 | 日本三级在线网站 | 久久国产精品视频 | 久久久精品网站 | 狠狠干五月天 | 日韩精品四区 | 亚洲精品久久久久久久久久久久久 | 天天爽夜夜爽精品视频婷婷 | 国产欧美精品在线 | 成人片网址 | 精品中文字幕在线 | 国产成人精品高清久久 | 国产主播第一页 | 精品乱码一区二区 | 欧美一级片 | 中文字幕乱码一区二区三区 |