項目開發中,真的有必要定義VO,BO,PO,DO,DTO這些嗎?


存在即是合理的,業務復雜,人員協同性要求高的場景下,這些規范性的東西不按着來雖然不會出錯,程序照樣跑,但是遵守規范會讓程序更具擴展性和可讀性,都是前輩血淋淋的寶貴經驗,為什么不用?

隨着現在后端編程標准化程度越來越高,各種編程模型層出不窮。作為Java開發人員,大部分人不免要接觸VO,BO,PO,DO,DTO之類的,但很多同學對這些概念一直以來都是雲里霧里,團隊開發過程中也總是處於混亂的狀態,抓起來就用,本來是規范性的東西,卻反而導致更加混亂了。

今天我們把這些概念掰開揉碎來講解一下,力求有一個清晰的理解,在開發中能有所助益。文中又理解不到位的,也歡迎大家斧正。

概念

  • VO(View Object):視圖對象,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。

  • DTO(Data Transfer Object):數據傳輸對象,這個概念來源於J2EE的設計模式,原來的目的是為了EJB的分布式應用提供粗粒度的數據實體,以減少分布式調用的次數,從而提高分布式調用的性能和降低網絡負載,但在這里,更符合泛指用於展示層與服務層之間的數據傳輸對象。

  • BO(Business Object):業務對象,把業務邏輯封裝為一個對象,這個對象可以包括一個或多個其它的對象。

  • PO(Persistent Object):持久化對象,它跟持久層(通常是關系型數據庫)的數據結構形成一一對應的映射關系,如果持久層是關系型數據庫,那么,數據表中的每個字段(或若干個)就對應PO的一個(或若干個)屬性。

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

如果光看這些概念,可能大部分人都理解,但還是很繞,具體用的時候還是不能很好區分,我們來橫向做個比較,理解會加深一些。

易混點一:VO和DTO

首先VO是最常用的,但對於這個概念,網上也是眾說紛紜,value object 或 view object,一般說視圖對象或者值對象,我更傾向理解為視圖對象。說白了它就是展示用的,不管展示方式是網頁,還是客戶端,還是APP,只要是這個東西是讓人看到的,我們就把它封裝為VO。

VO比較容易混淆的是DTO,DTO是展示層與服務層之間傳遞數據的對象,可以這樣說,對於絕大部分的應用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,那么既然有了VO,為什么還需要DTO呢?

我們舉例來說明一下:

某公司有一個后台服務,服務層有一個getUser的方法返回一個系統用戶,包含sex(性別)、年齡。對於服務層來說,DTO只從語義上定義,可能是這樣的:

{
 "gender":"男",
 "age":35
}

但這個服務同時供多個客戶端使用(不同門戶),而不同的客戶端對於表現層的要求有所不同,比如管理端要求顯示准確的年齡,而應用端為了保護客戶隱私,只需要顯示一個年齡段即可。

管理端VO:

{
 "gender":"男",
 "age":35
}

應用端VO:

{
 "gender":"男",
 "age":30~40
}

從這個例子可以看出,DTO很有存在的必要,根據職責單一原則,服務層只負責業務,與具體的表現形式無關,DTO不應該出現與表現形式的耦合,DTO定義的是原始數據,VO再對DTO數據進行解釋。這下VO和DTO用法就清晰很多了。

易混點二:BO和PO

PO是持久對象,這個很好理解,就是實體和數據庫字段的對應,一個PO的數據結構對應着庫中表的結構,表中的一條記錄就是一個PO屬性,大多數情況下,PO僅僅作為PO只是用來增刪改使用。

PO比較容易混淆的是BO,BO是業務對象,對應的是某個具體的業務塊,可以包含多個屬性、對象。簡單點來說,我們可以把BO看作是PO的組合。

我們舉例來說明一下:

PO-1是交易記錄對象,PO-2是登錄記錄對象,PO-3是商品瀏覽記錄對象,PO-4是添加購物車記錄對象,PO-5是搜索記錄對象,BO是個人網站行為對象,BO對象:{PO-1;PO-2;PO-3;PO-4;PO-5}。這樣做的優點不言而喻,維護代碼的時候查看BO,就能知道這塊邏輯涉及多少表(PO)。

易混點三:BO和DTO

搞清楚了BO和PO各自的用途后,我們會發現BO和DTO有重疊功能,一樣可以對PO進行排列組合,那BO的存在的意義是什么呢?

從用途上進行根本的區別,BO是業務對象,DTO是數據傳輸對象,雖然BO也可以排列組合數據,但它的功能是對內的,比如上個例子中的BO對象包括{PO-1;PO-2;PO-3;PO-4;PO-5}還有其他字段屬性,但在提供對外接口時,BO對象中的某些屬性對象可能用不到或者不方便對外暴露,那么此時DTO只需要在BO的基礎上,抽取自己需要的數據,然后對外提供。

在這個關系上,通常不會有數據內容的變化,內容變化要么在BO內部業務計算的時候完成,要么在解釋VO的時候完成。

DO

DO是領域對象,就是從現實世界中抽象出來的有形或無形的業務實體。事實上,DO和PO在絕大部分情況下是一一對應的。阿里巴巴的開發手冊中的定義DO等同於PO,即與數據庫表結構一一對應,通過DAO層向上傳輸數據源對象。


上一張圖,更加直觀的展示這些名詞使用的節點:

項目開發中,真的有必要定義VO,BO,PO,DO,DTO這些嗎?

總結

VO,BO,PO,DTO這樣分層還是很有意義的。尤其在團隊成員較多的情況下,結構更加一目了然,同時也能很大程度避免多端系統數據所需不一致時,有人修改屬性影響其他頁面。但也完全沒有必要教條主義,把這些全部用上,需要根據所開發的業務復雜度來取舍,如果本身業務邏輯不負責,照搬全上反而讓開發變的更復雜。

例如業務不復雜,根本沒有多端展示的差異化,VO可以直接拿掉,直接使用DTO傳輸到前端數據即可。

同時在使用過程中,最重要的是要在團隊中達成共識,概念一致,如果使用了這些,但各按各的理解來,甚至抓起來就直接用,反而會讓代碼變得更亂,還不如直接POJO、DTO打天下。

另附這些概念命名規范:

  • 數據對象:xxxPO,xxx即為數據表名。(也可DO)
  • 數據傳輸對象:xxxDTO,xxx為業務領域相關的名稱。
  • 展示對象:xxxVO,xxx一般為網頁名稱。
  • 業務對象:xxxBO,xxx是業務名稱。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM