DDD - 如何理解Entity与VO
文章目錄
- 概述
- 狀態
- 標識
- Entity 對比 VO
- 如何識別
概述
為了更好的理解 Entity與VO,我們需要先區分兩個概念: 狀態 、 標識
狀態
購物中的訂單狀態,相比大家都熟悉哈 , 比如 發貨中、 物流派送中、 商品已送達等等 。 一般訂單狀態都是使用一個字段來表示的,比如status, status不同的值代表不同的狀態。
但是這個status就是「訂單狀態」嗎?難不成狀態就是一個字段嗎?
我們聯想一下生活中的例子
- 商品已經是發貨「狀態」了
- 今天「狀態」不錯
- …
以 今天「狀態」不錯 為例,如果狀態就是一個字段, status=1 狀態好 status=0 狀態不好 。感覺不是很合理。
我們會發現,「狀態」實際上表示的是「目標對象在當前時刻所呈現出的內容」!在系統設計中中通過一個字段來表示狀態只是一種簡化手段!
「狀態」表示的是「當前時刻所呈現出的內容」, 那么說明了「狀態」是個快照/瞬態!也就是說,「目標對象」有多個「狀態」,「當前狀態」只是「目標對象」眾多「狀態」中的一個!
理解了什么是「狀態」以后,我們就可以來初步區分Entity和VO了:
-
Entity在整個生命周期中,有多個「狀態」,也就是說「狀態」是可變的(至于變不變就看實際情況了)
-
而VO在整個生命周期中,只有一個「狀態」,也就是說「狀態」不變
對于VO來說,因為「狀態」是不可變的,我們就可以用其「狀態」來表示VO!但是對于Entity來說,因為有多個「狀態」,且「狀態」是可變的,那我們如何來表示呢?
舉個例子:假設同一個買家在同一個賣家那里買了兩個同樣的商品,那兩個訂單里的信息都是一樣的,但是它是兩個不同的訂單,我們如何區分這兩個訂單呢?
那就不得不提到 「標識 」了
標識
說到「標識」,最先想到的一般是編程語言中的「引用」或「指針」
Order orderA = new Order("productA",...); Order orderB = new Order("productA",...); orderA.setProductName("productB");orderA和orderB雖然訂單信息(狀態)都相同,但是這是兩個不同的訂單 ,. 即使改了orderA的產品名稱(狀態),依然還是訂單A。
看似解決了「區分相同狀態的不同Entity」的問題,但是沒有解決Entity有多個狀態的問題。因為「標識」指向的是目標對象的當前狀態。
語言中的這種「標識」就是無法跨系統。比如,在分布式系統中,需要保證兩個系統中的對象是同一個對象,這種「隱式標識」是做不到的。
所以「隱式標識」并不能滿足我們的需求。我們需要「顯示標識」,「顯示標識」在現實中很常見:
- 身份證號碼就是每個人的「顯示標識」
- 產品編號就是產品的「顯示標識」
- …
比如 Order
public Class Order{orderNo // 顯示標識productstatus... }設置訂單號以后,無論訂單的狀態如何變化,只要訂單號不變,那么它就是同一個訂單。
所以,「標識」是另一個區分Entity和VO的關鍵點:
- Entity有標識
- VO沒有標識
注意標識并不一定只是一個字段,可能是多個字段的組合,這需要根據不同的業務邏輯來確定。
Entity 對比 VO
-
Entity是具有多個「狀態」的對象,「狀態」在其生命周期中可能會改變,通過「標識」來唯一確定這個對象
-
VO只有一個「狀態」,且是在創建時就確定的,也就是說VO是不可變的
那么我們如何在系統中識別哪些對象是Entity,哪些對象又是VO呢?
如何識別
一個對象是表示成Entity還是VO,取決于系統的關注點
舉個例子:
「商品」在「訂單系統」中是個VO,而在「商品管理系統」中是Entity
-
在「商品管理系統」中,系統需要關注「商品」的「狀態」,需要維護是否上架、庫存多少、各種屬性等信息(多種狀態)。就是說在「商品管理系統」中,商品狀態是可變的。所以它也有「標識」,即商品ID
-
「訂單系統」并不關心「商品」的「狀態」變化,它只關注在創建訂單時,這個「商品」的當前「狀態」是什么,并且在訂單創建完成后,這個「商品」的「狀態」就不會再改變了
在「商品管理系統」中,商品可以這樣表示:
public class Product {id // 商品標識namedescstatus... }而在「訂單系統」中,訂單是個Entity,商品是個VO,可以這么表示:
public class Order{orderNo // 訂單標識product:Productstatus... }public class Product {id // 這里不是標識,只是狀態namedescstatus... }注意這里的id并不是標識,這里的id實際上退化成了狀態的一部分,保留這個id是為了和「商品管理系統」進行交互,通過id從商品管理系統中查詢商品。當然還有其它方式,例如保存「商品管理系統」中該商品的歷史URL。
總結
以上是生活随笔為你收集整理的DDD - 如何理解Entity与VO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java Review - 使用Even
- 下一篇: DDD - 聚合与聚合根_如何理解 Re