一、實體
實體是領域模型中的一個對象,帶有業務含義的對象,集多個業務屬性,業務行為於一體。領域建模時,我們根據業務場景分析,找到跟業務邏輯相關的實體對象,然后按照實體間的關聯將多個對象進行聚合。
實體最大的特點是擁有唯一標識符,這個標識符貫穿整個軟件的生命周期,不隨業務流程和狀態變更后更改,在領域模型中以領域對象DO的形式存在。
如下代碼示例:人事領域里的人員考勤子域,考勤里面有員工對象,員工需要通過上班打卡,下班打卡完成一個完整的考勤行為,這個員工就是一個實體,因為每個人在公司都有工號,是標識這個人的唯一ID,不管他去上海還是北京出差打卡,他的員工ID都不會變化。
同時實體還會包含跟考勤相關的上班打卡和下班打卡方法,是一個充血模型。
/** * 人員實體 * @author test11 */ public class Person { //人員id private String id; //姓名 private String name; //地址 private Address address; //上班打卡 private void goWork(){ } //下班打卡 private void leaveWork(){ } }
二、值對象
如上代碼示例中,員工的信息由人員id,姓名,所在的省,市,街道組成,我們可以將省,市,街道抽象出來一個Address,構成一個地址的屬性集合,這個集合的名稱就是地址值對象。
所以值對象就是一個屬性集合,將不同的關聯屬性組合成了一個概念整體,具有整體概念和不可修改的特性。
/** * 地址值對象 */ public class Address { //省份 private String province; //城市 private String city; //街道 private String street; }
三、實體和值對象
實體和值對象都是微服務底層最基礎的領域對象,實現領域最基本的業務邏輯。
實體和值對象都是若干屬性的集合,實體一般是帶有業務含義的的對象,具有業務屬性,業務行為和業務邏輯。
值對象也是若干屬性的集合,但他只有數據初始化操作,不涉及數據修改,基本不包含業務邏輯。
值對象是屬於實體的一部分,如果值對象是單一屬性,則直接定義為實體的屬性,如果值對象是屬性集合,則將他設計為值對象類,值對象沒有ID,會被實體整體引用。
四、實體和值對象的數據庫形態
實體:
將領域模型映射到數據模型時,一個實體(DO)可能對應0,1,多個數據庫持久化對象(PO),大多數情況下DO和PO是一對一的關系,當DO只是暫住內存時,也可以不需要持久化。當用戶和角色兩個實體合並成權限實體時,一個DO則對應了多個PO。當用戶實體和訂單實體合並到一張表中時,這兩個DO的生成需要一個PO的拆分,這是多對一的關系。
值對象:
值對象的數據庫設計大都采用了反范式,實體對象的屬性值和值對象的屬性值集合以JSON形式保存在同一個數據庫表中。
上面的人員和地址的對應關系,設計數據庫表時可以有三種方式:
(1)把地址值對象的所有屬性加到人員實體表中:這種設計方式會破壞地址的業務含義和屬性完整

(2)創建人員實體的表,關聯地址實體表:增加了不必要的實體和表
(3)實體對象的屬性值和值對象的屬性值集合以JSON形式保存在同一個數據庫表中:數據建模時,可以將值對象的屬性集合嵌入到實體表中,保留對象的業務含義,同時減少了表的設計,一般是將值對象序列化成大對象JSON串后,嵌入到實體表中的
基於第三種方式的領域模型落地,現在許多數據庫都開始支持基於JSON串的CRUD操作了,當然,類似這樣值對象的設計,多了可能會使實體堆積一堆缺乏完整意義的屬性。
但是值對象不可變,在並發環境下獲取的永遠是相同的對象,不會被修改,所以值對象可以被多個實體並發引用,所以高並發場景下的領域對象一般優先設計為值對象而非實體,可以保證線程安全。
值對象還有一個重要作用,以數據冗余的方式記錄業務發生那一刻的數據,比如用戶聚合中包含了用戶(聚合根,也是實體)和地址值對象,訂單生成那一刻,用戶和地址信息以JSON的方式冗余進訂單數據中,這樣避免了訂單聚合每次都通過調用用戶的聚合根ID獲取最新用戶信息和地址,解耦了用戶聚合和訂單聚合,同時用戶實體和地址值對象也以冗余的方式,記錄了業務的快照數據,還原業務發生前后的場景。
五、貧血模型和充血模型
貧血模型:Spring的bean就是一種貧血模型,領域被用來作為屬性存儲的載體,而沒有實現具體方法,比如教育領域的校長,只會記錄他的年齡,職級,工作年限,而不會有他的一些行為的方法實現,單單用來作為屬性的存儲。
充血模型:實體不止包含對象的屬性,也包含他對應的行為的方法實現,而不止僅僅作為屬性存儲的載體。
參考書籍 ——《基於DDD和微服務的中台架構與實現》歐創新、鄧頔
參考書籍 ——《領域驅動設計》Eric Evans
參考書籍 ——《架構真經》Martin L. Abbott