DDD 中的值對象和實體

背景

在 DDD 中有兩個比較重要的對象,即值對象和實體。而聚合根就是由這兩個對象組成的,所以業務建模前我們都會先定義好實體和值對象,然後再構建聚合根,所以再研究複雜的聚合根之前我們先來研究相對簡單但是基礎的值對象和實體吧。

定義

舉例說明

拿常見的電商項目來說,每個用戶一般會有一個唯一標識比如身份證。或者唯一 id,而用戶會有收貨地址,收貨地址是沒有唯一標識的,是依賴實體而存在的,沒有用戶地址也就失去了存在的意義。所以收貨地址是值對象。

兩者對應的關係大致是如下如果在數據庫中設計,可能是拆裝兩張表或者使用一張,還有一種對應關係就是使用 json 去嵌套。這種好處就是不用多維護一張表,查詢使用都很方便,唯一的缺點就是修改太麻煩了,畢竟是 json

在我們構建值對象的時候,一般都是會使用 Builder 模式去構建值對象,然後不暴露 set 方法,原因如下:在傳統通過 new 構造對象,然後各種 set 方法,在我們出現 bug 或者一些業務排查的時候,整個對象在各種地方 set 了屬性,我們無法準確定位到對象的某個屬性在哪個時候悄悄被改變了,排查起來特別困難,而值對象一般是不可變類似一種配置的概念,正好特別適合這種方式去構造。但是這種方式也會有一定缺陷,比如某些三方框架都會調用無參構造方法去初始化,然而使用了 Builder 模式私有化了構造方法,就會有意想不到的報錯,但這種錯誤一般在我們的可控範圍,所以具體是否使用這種方式去構造實體也是自己在落地 DDD 去考慮,但是不用強制去執行,建議靈活應用。畢竟 DDD 在所有人的理解中都不太一樣,團隊中使用起來覺得好用合適纔是最好的。

總結

實體和值對象有時候很容易區分,有時候又不太容易區分,不過主要還是看有沒有唯一標識,如果有唯一表示就是實體,如果能夠獨立存在也是實體,否則則是值對象,比如像上面的地址,如果脫離了用戶其實就沒有實際意義了。上面的實體和值對象是我自己的理解,如果覺得有什麼偏差歡迎大家補充。期望在 DDD 的設計上與大家共同進步。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/LFJXMlcTBbyfCr85SVozag