領域驅動設計,建模要素實體(Entity)的本質

實體和值對象是領域驅動設計構建模型的重要元素之一,DDD中要求實體是唯一的且可持續變化的。唯一性標識了對象自身以區別其他對象,可變性反映了實體自身的狀態和行為的變化。

領域驅動設計中的實體Entity

我們在進行面向對象設計時一般會對系統中的概念進行抽象,設計系統中的關鍵類,並關注與該概念相關的屬性和行為。在領域驅動設計中,實體Enity也是我們進行領域模型抽象的關鍵因素。在系統所關注的領域中,存在很多對象不是由它們的屬性來定義,而是通過一系列的連續性(continuity)和標識(identity)來進行定義的。如果一個對象在生命週期中能夠保持連續性,並且獨立於它的屬性,那它就是一個實體。

領域驅動設計中的實體有兩個最為核心的特徵:唯一性和可變性

領域驅動設計,建模要素實體(Entity)的本質

唯一性

實體對象具備唯一標識符用於作為區別於其他對象的唯一條件。但屬性並不是實體的區分標誌,只要是實體對象的唯一性標識不同,則認為他們是不同的實體對象。

實體的唯一標識的形式在不同業務場景下有不同要求。比如:

  • 業務不要求實體標識具有業務相關性,我們可以簡單的通過自增整型ID或UUID作為實體標識。
  • 業務需要實體標識具有業務相關性,則我們需要生成業務相關的實體標識。

在電商系統中,訂單是最為基礎和普遍的概念。對於訂單而言,我們惡意將其抽象為OrderEnity。在對訂單的實體標識選擇上一般要具備業務相關性,比如訂單編號能夠反映時間、訂單類型等等,基於這種業務需求我們需要設計訂單號的標識規則,而不能簡單的使用自增整型ID來實現了。需要注意的是,實體的標識要具備唯一性,因此,對標識的生成策略需要在技術層面保證其唯一性的實現。

委派標識和領域標識

  • 領域標識:基於領域實體概念分析確定的唯一身份標識,
  • 委派標識:是指某些ORM、數據庫等組件擁有自己的方式來處理對象的身份標識,以數據庫MySQL為例,在表中存在自增整型ID作為主鍵以標識數據記錄,這種迎合數據庫或其他組件的對象標識形式稱之為委派標識,委派標識和領域實體標識是兩個獨立概念,是分屬於不同關注維度的標識劃分。

可變性

實體的可變性表現在對象狀態和行為的變化,實體不是通過屬性來定義,即使屬性完全相同也可能是兩個不同的對象。實體本身具有自己的生命週期,實體狀態隨著時間不斷變化和演進。實體本身會體現出相關的業務行為,業務行為和實體狀態會實體屬性或造成影響和改變。

以訂單為例,訂單實體具備典型的生命週期:

領域驅動設計,建模要素實體(Entity)的本質

從創建到關閉一般會存在幾個不同的狀態,比如未支付、已支付、已發貨、已關閉等。訂單從下單開始,隨著不同的業務活動訂單的屬性不斷變化。

總結

領域驅動設計過程中對領域進行抽象、建模過程中實體是非常重要的概念,實體有自己的生命週期,且具有唯一性和可變性兩個根本性特徵,對於一個對象是否應該設計為實體要從實體的本質去權衡,


分享到:


相關文章: