關於DDD的概念筆記

  • 2020 年 2 月 26 日
  • 筆記

前言

看過很多關於 DDD 的文章, 也買過一些書籍, 但是發現內容冗長, 大部分時間用來理解名詞含義, 而忽略裡面的設計精華.

下面是我基於極客時間《DDD實戰課專欄》整理的一些名詞解釋, 裡面也摻雜了一些個人理解和說明, 希望能對你理解起來有所幫助.

領域和子域

領域顧名思義, 表示的是特定的一種範圍

舉例說明:

我們把領域比作為整體的業務系統, 在業務系統裡面也包含很多子系統(比如用戶中心、訂單中心、商品中心), 我們將這些子系統稱為子域, 是依據領域的範圍繼續劃分出來的更小的業務範圍,

在用戶中心裏面也可以繼續劃分為VIP和普通用戶系統等, 這也就是子域進一步劃分為子子域, 這也是正常系統演進的過程.

一個複雜的系統, 通過逐步劃分子域, 形成了業務上的拆解, 最終目的是降低業務理解和系統實現的複雜度

如何理解核心域、通用域和支撐域

核心域

可理解為最核心的業務(主線), 基本屬於業務的核心競爭力了.

不同公司核心域是不同的, 比如有側重品質, 有側重物流服務, 也有客戶服務

通用域

被多個子域共同使用的稱之為通用域, 比如認證、許可權等

支撐域

一些公司個性化的業務

什麼是通用語言

通過團隊溝通最終達成的共識, 能夠簡單、清晰、準確的描述我們業務涵義和規則的語言就是通用語言.

簡單來說就是可以解決交流障礙問題, 統一產品、研發、測試、運營等人員之間的業務術語交流

通用語言名詞給領域對象命名, 比如商品、訂單等, 對應實體模型. 動詞表示一個動作或事件, 比如下訂單、取消訂單、訂單已取消、訂單已付款、瀏覽商品、加入購物車等

定義好通用語言, 將通用語言中的業務需求轉換為的程式碼實現, 就會非常容易了, 最終實現了 業務語言與程式碼語言的統一

限界上下文

限界就是領域的邊界,而上下文則是語義環境

我們都知道語言的魅力, 一句 今天交作業了沒, 在不同的場景下就會賦予不同的含義, 同學問你可能是真的問你交作業了沒有, 如果你的女朋友問你, 可能又是另一個含義了.

所以我們必須要明確在一個業務場景下使用的業務語言只有一個含義, 避免理解起來出現二義性, 否則會出現認知偏差, 結果就會溝通起來很累.

只有在限界上下文的條件下, 通用語言才可能會避免出現二義性.

為什麼講 限界上下文可以作為微服務拆分的重要依據?

之前我們講到劃分子域, 劃分後我們需要達成通用語言

通用語言永遠只表示一個含義, 需要給定一個有效範圍(限界上下文, 劃分領域邊界), 最終可映射一個完成的服務實體.

實體和值對象

實體

每個實體對象都有唯一的 ID。我們可以對一個實體對象進行多次修改,修改後的數據和原來的數據可能會大不相同

更簡化的理解為: 商品是商品上下文的一個實體,通過唯一的商品 ID 來標識,不管這個商品的數據如何變化,商品的 ID 一直保持不變,它始終是同一個商品

比如我們在開發電商系統中, 我們可以給定商品實體、訂單實體等等, 然後我們再繼續圍繞這些實體開展工作

值對象

值對象是實體的一部分, 負責延展、擴充實體對象, 屬於實體對象的一部分

實體對象映射的是真實的業務對象,具有業務屬性、業務事件、業務行為, 而值對象是不包含業務邏輯的.

比如在實體中我們給定了訂單實體, 訂單實體一般對應著地址, 我們可以講地址是對訂單的一種擴充, 所以地址為值對象.

實體和值對象舉例

以註冊用戶和地址舉例:

在電商購物這個上下文角度觀察: 註冊用戶可以看作一個實體, 而對應的地址可以看作為一個值對象

而在地區統計系統上下文角度觀察: 地址可以算作一個實體, 而註冊用戶是可以作為一個值對象存在的.

實體可修改,值對象不可修改,只可以整體替換。實體是實實在在的業務對象,值對象只是對對象的描述。值對象依附以實體,實體沒了值對象也就沒了。

聚合和聚合根

通過上面的理論, 我們劃分出了 限界上下文, 劃分了領域的邊界.

而後我們又分析找出了 實體 和 值對象,

下一步我們將實體、值對象進行聚合, 完成限界上下文 下的領域建模

聚合

實體 和 值對象 是很基礎的領域對象。實體一般對應業務對象,它具有業務屬性和業務行為;而值對象主要是屬性集合,對實體的狀態和特徵進行描述。但實體和值對象都只是個體化的對象,它們的行為表現出來的是個體的能力。

我們劃分的實體對象之間大多都是存在聯繫的, 彼此協作完成一個複雜的業務系統, 這裡就需要我們使用聚合(或成為組合實體對象).

聚合根

當我們需要將一些實體對象組合起來完成 限界上下文 的領域建模時, 是需要將我們的實體對象規則控制、協調的, 這就是我們聚合根的作用了.

首先它作為實體本身,擁有實體的屬性和業務行為,實現自身的業務邏輯。其次它作為聚合的管理者,在聚合內部負責協調 實體 和 值對象 按照固定的業務規則協同完成共同的業務邏輯。

以電商裡面的訂單舉例

  1. 訂單在聚合里是聚合根,與訂單關聯的有訂單明細和收貨地址。
  2. 訂單明細包括商品ID,商品名稱,價格以及數量等資訊,由於訂單明細是多個,它是一個集合,它被設計為實體,被訂單引用。
  3. 而訂單只有一個收貨地址,這個收貨地址的值來源於你個人中心維護的收貨地址,收貨地址只能被整體替換,所以它被設計為值對象。

關係圖例

  1. 一套業務領域劃分多個 限界上下文子域
  2. 一個 限界上下文 子域對應多個聚合
  3. 一個聚合裡面劃分進多個 實體 和 值對象, 並實現一個聚合根
  4. 一個聚合根調度多個 實體、值對象

結語

本文主要為概念性說明, 借鑒於《DDD實戰課