淺析VO、DTO、DO、BO的概念、區別和用處

一、概念

  • VO (View Object),用於表示一個與前端進行交互的視圖對象,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。實際上,這裏的 VO 只包含前端需要展示的數據,對於前端不需要的數據,比如數據創建和修改的時間等字段,出於減少傳輸數據量大小和保護數據庫結構不外泄的目的,不應該在 VO 中體現出來。

  • DTO(Data Transfer Object),用於表示一個數據傳輸對象,DTO 通常用於展示層(Controller)和服務層(Service)之間的數據傳輸對象。DTO 與 VO 概念相似,並且通常情況下字段也基本一致。但 DTO 與 VO 又有一些不同,這個不同主要是設計理念上的,比如 API 服務需要使用的 DTO 就可能與 VO 存在差異。

  • DO(Data Object) ,持久化對象,它跟持久層(Dao)的數據結構形成一一對應的映射關係。如果持久層是關係型數據庫,那麼數據庫表中的每個字段就對應PO的一個屬性,常是entuty實體類。

  • BO(Business Object):業務對象,就是從現實世界中抽象出來的有形或無形的業務實體。

阿里Java開發手冊分層領域模型:
阿里巴巴Java開發手冊

二、爲什麼會存在Vo?

項目中,看到別人直接把DTO,寫上swagger註釋,直接返回前端。那麼思考一下,爲什麼不建議這麼做,不直接把DTO返回給前端。

  • 從開發過程講,前後端首先會以vo和param作爲返回、傳參的協議的定義,再定義協議之前,都沒有實際的業務邏輯的處理,也就不會存在dto。

  • 從項目的整體考慮,如果把dto作爲傳給前端的對象,那麼service層返回dto,service層的所有的方法不一定都是public方法,也有private方法,如果private方法也返回dto,那麼也就是說有些dto不是提供給前端的,有些是給前端的,這樣就會亂,沒有了隔離性。

  • 從字段的修改來說,service層的方法是可以共用的,一個service方法返回的dto,可能會被很多個controlller方法使用到,即使目前不會,將來也可能會,dto會有很多參數,比如包含了主表信息,子表信息,而傳給前端的vo只有dto的一部分信息,而且不同請求給前端看到的數據不一樣,所以dto是共用的,vo是個性化的,如果直接把dto提供給前端,將會導致耦合性非常大,一旦一個接口的需求變了,修改了dto,增加了一個字段,將會導致接口直接把這個新增的字段返回給了前端,導致(接口輸出數據多餘,和不安全性)。同理,如果由於某個需求,把dto展示給前端的接口說要刪除某一個字段,那麼因爲這個dto被很多接口引用,一刪除就會導致出問題。

所以,總整體性結構而言:vo是必須存在的,不能把dto直接返回給前端。高內聚,低耦合。


三、其他問題

1. VO可以複用嗎?

比如,一個接口需要VO,另一個接口需要VO加上別的一些數據,這種情況,是繼承VO使用,還是再寫一個VO?

答案:VO最好不要複用。VO目的就是解耦,應該是並列關係的,如果存在複用,那麼就可能導致,一方修改影響另一方。一旦存在繼承關係,繼承來繼承去,最後關係就會變得很亂,不好維護。


2. Controller層接收的參數是VO還是DTO?

Controller層接收的應該是VO,但是根據情況而定,尤其是前後分離,有特定的前端開發人員時,因爲DTO往往會添加很多額外的數據信息,打個比方,用戶新增,往往前端傳遞的是賬戶名、密碼、創建人標識等等很少的信息,但是DTO作爲一箇中轉數據,會添加例如更新人、用戶狀態等等其他的信息,如果前端傳遞的是DTO,如此多的額外信息會給前端造成很多問題。如果是小項目的話,前後端都是一個人在進行,那就無所謂了,後端需要哪些,不需要哪些心裏有數,傳遞DTO就無所謂了。

一般的數據傳遞是,前端傳遞VO給接口(Controller),接口將VO轉爲DTO傳遞給service,service將DTO分解爲DO,調用領域服務進行調度,然後逆向轉爲VO或者其他的返回結果,傳遞給前臺。


參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章