java里面Dto對象跟VO的區別


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

javaBean 是一種JAVA語言寫成的可重用組件。為寫成JavaBean,類必須是具體的和公共的,並且具有無參數的構造器。JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性。眾所周知,屬性名稱符合這種模式,其他Java 類可以通過自身機制發現和操作這些JavaBean 的屬性。

VO即value object值對象
主要體現在視圖的對象,對於一個WEB頁面將整個頁面的屬性封裝成一個對象。然后用一個VO對象在控制層與視圖層進行傳輸交換。

DTO (經過處理后的PO,可能增加或者減少PO的屬性):
Data Transfer Object數據傳輸對象
主要用於遠程調用等需要大量傳輸對象的地方。
比如我們一張表有100個字段,那么對應的PO就有100個屬性。
但是我們界面上只要顯示10個字段,
客戶端用WEB service來獲取數據,沒有必要把整個PO對象傳遞到客戶端,
這時我們就可以用只有這10個屬性的DTO來傳遞結果到客戶端,這樣也不會暴露服務端表結構.到達客戶端以后,如果用這個對象來對應界面顯示,那此時它的身份就轉為VO。

POJO(POJO是一種概念或者接口,身份及作用隨環境變化而變化) :
POJO有一些private的參數作為對象的屬性。然后針對每個參數定義了get和set方法作為訪問的接口
plain ordinary java object 簡單java對象
即POJO是一個簡單的普通的Java對象,它不包含業務邏輯或持久邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不繼承或不實現任何其它Java框架的類或接口。
POJO對象有時也被稱為Data對象,大量應用於表現現實中的對象。
一個POJO持久化以后就是PO。
直接用它傳遞、傳遞過程中就是DTO
直接用來對應表示層就是VO

 

VO與DTO的區別
既然DTO是展示層與服務層之間傳遞數據的對象,為什么還需要一個VO呢?對!對於絕大部分的應用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,因此沒必要多此一舉,但不要忘記這是實現層面的思維,對於設計層面來說,概念上還是應該存在VO和DTO,因為兩者有着本質的區別,DTO代表服務層需要接收的數據和返回的數據,而VO代表展示層需要顯示的數據。

用一個例子來說明可能會比較容易理解:

例如Service層有一個getUser的方法返回一個系統用戶,其中有一個屬性是gender(性別),對於Service層來說,它只從語義上定義:1-男性,2-女性,0-未指定,而對於展示層來說,它可能需要用“帥哥”代表男性,用“美女”代表女性,用“秘密”代表未指定。說到這里,可能你還會反駁,在服務層直接就返回“帥哥美女”不就行了嗎?對於大部分應用來說,這不是問題,但設想一下,如果需求允許客戶可以定制風格,而不同風格對於“性別”的表現方式不一樣,又或者這個服務同時供多個客戶端使用(不同門戶),而不同的客戶端對於表現層的要求有所不同,那么,問題就來了。再者,回到設計層面上分析,從職責單一原則來看,服務層只負責業務,與具體的表現形式無關,因此,它返回的DTO,不應該出現與表現形式的耦合。
理論歸理論,這到底還是分析設計層面的思維,是否在實現層面必須這樣做呢?一刀切的做法往往會得不償失,下面我馬上會分析應用中如何做出正確的選擇。

VO與DTO的應用
上面只是用了一個簡單的例子來說明VO與DTO在概念上的區別,本節將會告訴你如何在應用中做出正確的選擇。

在以下才場景中,我們可以考慮把VO與DTO二合為一(注意:是實現層面):

當需求非常清晰穩定,而且客戶端很明確只有一個的時候,沒有必要把VO和DTO區分開來,這時候VO可以退隱,用一個DTO即可,為什么是VO退隱而不是DTO?回到設計層面,Service層的職責依然不應該與View層耦合,所以,對於前面的例子,你很容易理解,DTO對於“性別”來說,依然不能用“帥哥美女”,這個轉換應該依賴於頁面的腳本(如JavaScript)或其他機制(JSTL、EL、CSS)
即使客戶端可以進行定制,或者存在多個不同的客戶端,如果客戶端能夠用某種技術(腳本或其他機制)實現轉換,同樣可以讓VO退隱

以下場景需要優先考慮VO、DTO並存:

因為某種技術原因,比如某個框架(如Flex)提供自動把POJO轉換為UI中某些Field時,可以考慮在實現層面定義出VO,這個權衡完全取決於使用框架的自動轉換能力帶來的開發和維護效率提升與設計多一個VO所多做的事情帶來的開發和維護效率的下降之間的比對。

如果頁面出現一個“大視圖”,而組成這個大視圖的所有數據需要調用多個服務,返回多個DTO來組裝(當然,這同樣可以通過服務層提供一次性返回一個大視圖的DTO來取代,但在服務層提供一個這樣的方法是否合適,需要在設計層面進行權衡)。

JavaBean 是一種JAVA語言寫成的可重用組件。為寫成JavaBean,類必須是具體的和公共的,並且具有無參數的構造器。JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性。眾所周知,屬性名稱符合這種模式,其他Java 類可以通過自身機制發現和操作這些JavaBean 的屬性。
VO即value object值對象
主要體現在視圖的對象,對於一個WEB頁面將整個頁面的屬性封裝成一個對象。然后用一個VO對象在控制層與視圖層進行傳輸交換。
DTO (經過處理后的PO,可能增加或者減少PO的屬性):
Data Transfer Object數據傳輸對象
主要用於遠程調用等需要大量傳輸對象的地方。
比如我們一張表有100個字段,那么對應的PO就有100個屬性。
但是我們界面上只要顯示10個字段,
客戶端用WEB service來獲取數據,沒有必要把整個PO對象傳遞到客戶端,
這時我們就可以用只有這10個屬性的DTO來傳遞結果到客戶端,這樣也不會暴露服務端表結構.到達客戶端以后,如果用這個對象來對應界面顯示,那此時它的身份就轉為VO。
POJO(POJO是一種概念或者接口,身份及作用隨環境變化而變化) :
POJO有一些private的參數作為對象的屬性。然后針對每個參數定義了get和set方法作為訪問的接口
plain ordinary java object 簡單java對象
即POJO是一個簡單的普通的Java對象,它不包含業務邏輯或持久邏輯等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不繼承或不實現任何其它Java框架的類或接口。
POJO對象有時也被稱為Data對象,大量應用於表現現實中的對象。
一個POJO持久化以后就是PO。
直接用它傳遞、傳遞過程中就是DTO
直接用來對應表示層就是VO

經常會接觸到VO,DO,DTO的概念,本文從領域建模中的實體划分和項目中的實際應用情況兩個角度,對這幾個概念進行簡析。

得出的主要結論是:在項目應用中,VO對應於頁面上需要顯示的數據(表單),DO對應於數據庫中存儲的數據(數據表),DTO對應於除二者之外需要進行傳遞的數據。

一、實體類

百度百科中對於實體類的定義如下:

實體類的主要職責是存儲和管理系統內部的信息,它也可以有行為,甚至很復雜的行為,但這些行為必須與它所代表的實體對象密切相關。

根據以上定義,我們可以了解到,實體類有兩方面內容,存儲數據和執行數據本身相關的操作。這兩方面內容對應到實現上,最簡單的實體類是POJO類,含有屬性及屬性對應的set和get方法,實體類常見的方法還有用於輸出自身數據的toString方法。

二、領域模型中的實體類

領域模型中的實體類分為四種類型:VO、DTO、DO、PO,各種實體類用於不同業務層次間的交互,並會在層次內實現實體類之間的轉化。

業務分層為:視圖層(VIEW+ACTION),服務層(SERVICE),持久層(DAO)

相應各層間實體的傳遞如下圖

項目中我們並沒有嚴格遵循這種傳遞關系,但這種和業務層次的關聯對我們理解各實體類的作用是有幫助的。(我們沒有接觸到PO的原因,我理解為ORM對PO進行了封裝)

以下是資料的原文,上圖是基於此繪制的:

概念:

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

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

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

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

模型:

   下面以一個時序圖建立簡單模型來描述上述對象在三層架構應用中的位置

l 用戶發出請求(可能是填寫表單),表單的數據在展示層被匹配為VO。

l 展示層把VO轉換為服務層對應方法所要求的DTO,傳送給服務層。

l 服務層首先根據DTO的數據構造(或重建)一個DO,調用DO的業務方法完成具體業務。

l 服務層把DO轉換為持久層對應的PO(可以使用ORM工具,也可以不用),調用持久層的持久化方法,把PO傳遞給它,完成持久化操作。

l 對於一個逆向操作,如讀取數據,也是用類似的方式轉換和傳遞,略。

三、項目中的實體類

項目中常見的實體類有VO,DO和DTO,命名規則也常是以相應字符串結尾,如*VO.Java。但是DTO不總是遵循這個規則,而通常與他的用途有關,如寫成*Query.Java,表示存儲了一個查詢條件。項目中實體類出現的業務層次也沒有這么嚴格,例如我們可以在視圖層就組裝一個DO,也可以將一個VO從持久層傳出來,所以與業務分層相關聯的划分方法顯得有些冗余。從項目代碼中抽象出的理解是:VO對應於頁面上需要顯示的數據,DO對應於數據庫中存儲的數據,DTO對應於除二者之外需要進行傳遞的數據。

不復制粘貼,寫的通俗易懂一點。由於會分包分層,避免亂套。就有了這些對象類型
VO(value object)
用於返回給前端交互。傳給前端的對象被稱作VO(web層)。也就是前端調用你restful接口你返回的對象。

DTO(Data Transfer Object)
用於業務層(biz層)的處理

一般來說的流程就是
從數據庫中取出的對象,比如是data ,那么就先需要轉換成dataDTO處理數據。然后返回到restful前轉換成需要的VO

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

原文地址:https://ask.csdn.net/questions/692933?sort=id


免責聲明!

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



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