欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

一遍文章搞清楚VO、DTO、DO、PO的概念、區(qū)別-創(chuàng)新互聯(lián)

作者:Cat Qi

創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供左權(quán)網(wǎng)站建設(shè)、左權(quán)做網(wǎng)站、左權(quán)網(wǎng)站設(shè)計、左權(quán)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、左權(quán)企業(yè)網(wǎng)站模板建站服務(wù),十年左權(quán)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

一、概念:

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

  • DTO(Data Transfer Object):數(shù)據(jù)傳輸對象,這個概念來源于J2EE的設(shè)計模式,原來的目的是為了EJB的分布式應(yīng)用提供粗粒度的數(shù)據(jù)實(shí)體,以減少分布式調(diào)用的次數(shù),從而提高分布式調(diào)用的性能和降低網(wǎng)絡(luò)負(fù)載,但在這里,我泛指用于展示層與服務(wù)層之間的數(shù)據(jù)傳輸對象。

  • DO(Domain Object):領(lǐng)域?qū)ο?,就是從現(xiàn)實(shí)世界中抽象出來的有形或無形的業(yè)務(wù)實(shí)體。

  • PO(Persistent Object):持久化對象,它跟持久層(通常是關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)結(jié)構(gòu)形成一一對應(yīng)的映射關(guān)系,如果持久層是關(guān)系型數(shù)據(jù)庫,那么,數(shù)據(jù)表中的每個字段(或若干個)就對應(yīng)PO的一個(或若干個)屬性。

二、模型:

下面以一個時序圖建立簡單模型來描述上述對象在三層架構(gòu)應(yīng)用中的位置

一遍文章搞清楚VO、DTO、DO、PO的概念、區(qū)別

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

  • 展示層把VO轉(zhuǎn)換為服務(wù)層對應(yīng)方法所要求的DTO,傳送給服務(wù)層。

  • 服務(wù)層首先根據(jù)DTO的數(shù)據(jù)構(gòu)造(或重建)一個DO,調(diào)用DO的業(yè)務(wù)方法完成具體業(yè)務(wù)。

  • 服務(wù)層把DO轉(zhuǎn)換為持久層對應(yīng)的PO(可以使用ORM工具,也可以不用),調(diào)用持久層的持久化方法,把PO傳遞給它,完成持久化操作。

  • 對于一個逆向操作,如讀取數(shù)據(jù),也是用類似的方式轉(zhuǎn)換和傳遞,略。

三、VO與DTO的區(qū)別

大家可能會有個疑問(在筆者參與的項(xiàng)目中,很多程序員也有相同的疑惑):既然DTO是展示層與服務(wù)層之間傳遞數(shù)據(jù)的對象,為什么還需要一個VO呢?對!對于絕大部分的應(yīng)用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,因此沒必要多此一舉,但不要忘記這是實(shí)現(xiàn)層面的思維,對于設(shè)計層面來說,概念上還是應(yīng)該存在VO和DTO,因?yàn)閮烧哂兄举|(zhì)的區(qū)別,DTO代表服務(wù)層需要接收的數(shù)據(jù)和返回的數(shù)據(jù),而VO代表展示層需要顯示的數(shù)據(jù)。

用一個例子來說明可能會比較容易理解:例如服務(wù)層有一個getUser的方法返回一個系統(tǒng)用戶,其中有一個屬性是gender(性別),對于服務(wù)層來說,它只從語義上定義:1-男性,2-女性,0-未指定,而對于展示層來說,它可能需要用“帥哥”代表男性,用“美女”代表女性,用“秘密”代表未指定。說到這里,可能你還會反駁,在服務(wù)層直接就返回“帥哥美女”不就行了嗎?

對于大部分應(yīng)用來說,這不是問題,但設(shè)想一下,如果需求允許客戶可以定制風(fēng)格,而不同風(fēng)格對于“性別”的表現(xiàn)方式不一樣,又或者這個服務(wù)同時供多個客戶端使用(不同門戶),而不同的客戶端對于表現(xiàn)層的要求有所不同,那么,問題就來了。再者,回到設(shè)計層面上分析,從職責(zé)單一原則來看,服務(wù)層只負(fù)責(zé)業(yè)務(wù),與具體的表現(xiàn)形式無關(guān),因此,它返回的DTO,不應(yīng)該出現(xiàn)與表現(xiàn)形式的耦合。

理論歸理論,這到底還是分析設(shè)計層面的思維,是否在實(shí)現(xiàn)層面必須這樣做呢?一刀切的做法往往會得不償失,下面我馬上會分析應(yīng)用中如何做出正確的選擇。

四、VO與DTO的應(yīng)用

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

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

  • 需求非常清晰穩(wěn)定,而且客戶端很明確只有一個的時候,沒有必要把VO和DTO區(qū)分開來,這時候VO可以退隱,用一個DTO即可,為什么是VO退隱而不是DTO?回到設(shè)計層面,服務(wù)層的職責(zé)依然不應(yīng)該與展示層耦合,所以,對于前面的例子,你很容易理解,DTO對于“性別”來說,依然不能用“帥哥美女”,這個轉(zhuǎn)換應(yīng)該依賴于頁面的腳本(如JavaScript)或其他機(jī)制(JSTL、EL、CSS)

  • 即使客戶端可以進(jìn)行定制,或者存在多個不同的客戶端,如果客戶端能夠用某種技術(shù)(腳本或其他機(jī)制)實(shí)現(xiàn)轉(zhuǎn)換,同樣可以讓VO退隱

以下場景需要優(yōu)先考慮VO、DTO并存:

  • 上述場景的反面場景

  • 因?yàn)槟撤N技術(shù)原因,比如某個框架(如Flex)提供自動把POJO轉(zhuǎn)換為UI中某些Field時,可以考慮在實(shí)現(xiàn)層面定義出VO,這個權(quán)衡完全取決于使用框架的自動轉(zhuǎn)換能力帶來的開發(fā)和維護(hù)效率提升與設(shè)計多一個VO所多做的事情帶來的開發(fā)和維護(hù)效率的下降之間的比對。

  • 如果頁面出現(xiàn)一個“大視圖”,而組成這個大視圖的所有數(shù)據(jù)需要調(diào)用多個服務(wù),返回多個DTO來組裝(當(dāng)然,這同樣可以通過服務(wù)層提供一次性返回一個大視圖的DTO來取代,但在服務(wù)層提供一個這樣的方法是否合適,需要在設(shè)計層面進(jìn)行權(quán)衡)。

五、DTO與DO的區(qū)別

首先是概念上的區(qū)別,DTO是展示層和服務(wù)層之間的數(shù)據(jù)傳輸對象(可以認(rèn)為是兩者之間的協(xié)議),而DO是對現(xiàn)實(shí)世界各種業(yè)務(wù)角色的抽象,這就引出了兩者在數(shù)據(jù)上的區(qū)別,例如UserInfo和User,對于一個getUser方法來說,本質(zhì)上它永遠(yuǎn)不應(yīng)該返回用戶的密碼,因此UserInfo至少比User少一個password的數(shù)據(jù)。而在領(lǐng)域驅(qū)動設(shè)計中,正如第一篇系列文章所說,DO不是簡單的POJO,它具有領(lǐng)域業(yè)務(wù)邏輯。

六、DTO與DO的應(yīng)用

從上一節(jié)的例子中,細(xì)心的讀者可能會發(fā)現(xiàn)問題:既然getUser方法返回的UserInfo不應(yīng)該包含password,那么就不應(yīng)該存在password這個屬性定義,但如果同時有一個createUser的方法,傳入的UserInfo需要包含用戶的password,怎么辦?

在設(shè)計層面,展示層向服務(wù)層傳遞的DTO與服務(wù)層返回給展示層的DTO在概念上是不同的,但在實(shí)現(xiàn)層面,我們通常很少會這樣做(定義兩個UserInfo,甚至更多),因?yàn)檫@樣做并不見得很明智,我們完全可以設(shè)計一個完全兼容的DTO,在服務(wù)層接收數(shù)據(jù)的時候,不該由展示層設(shè)置的屬性(如訂單的總價應(yīng)該由其單價、數(shù)量、折扣等決定),無論展示層是否設(shè)置,服務(wù)層都一概忽略,而在服務(wù)層返回數(shù)據(jù)時,不該返回的數(shù)據(jù)(如用戶密碼),就不設(shè)置對應(yīng)的屬性。

對于DO來說,還有一點(diǎn)需要說明:為什么不在服務(wù)層中直接返回DO呢?這樣可以省去DTO的編碼和轉(zhuǎn)換工作,原因如下:

  • 兩者在本質(zhì)上的區(qū)別可能導(dǎo)致彼此并不一一對應(yīng),一個DTO可能對應(yīng)多個DO,反之亦然,甚至兩者存在多對多的關(guān)系。

  • DO具有一些不應(yīng)該讓展示層知道的數(shù)據(jù)

  • DO具有業(yè)務(wù)方法,如果直接把DO傳遞給展示層,展示層的代碼就可以繞過服務(wù)層直接調(diào)用它不應(yīng)該訪問的操作,對于基于AOP攔截服務(wù)層來進(jìn)行訪問控制的機(jī)制來說,這問題尤為突出,而在展示層調(diào)用DO的業(yè)務(wù)方法也會因?yàn)槭聞?wù)的問題,讓事務(wù)難以控制。

  • 對于某些ORM框架(如Hibernate)來說,通常會使用“延遲加載”技術(shù),如果直接把DO暴露給展示層,對于大部分情況,展示層不在事務(wù)范圍之內(nèi)(Open session in view在大部分情況下不是一種值得推崇的設(shè)計),如果其嘗試在Session關(guān)閉的情況下獲取一個未加載的關(guān)聯(lián)對象,會出現(xiàn)運(yùn)行時異常(對于Hibernate來說,就是LazyInitiliaztionException)。

  • 從設(shè)計層面來說,展示層依賴于服務(wù)層,服務(wù)層依賴于領(lǐng)域?qū)?,如果把DO暴露出去,就會導(dǎo)致展示層直接依賴于領(lǐng)域?qū)?,這雖然依然是單向依賴,但這種跨層依賴會導(dǎo)致不必要的耦合。

對于DTO來說,也有一點(diǎn)必須進(jìn)行說明,就是DTO應(yīng)該是一個“扁平的二維對象”,舉個例子來說明:如果User會關(guān)聯(lián)若干個其他實(shí)體(例如Address、Account、Region等),那么getUser()返回的UserInfo,是否就需要把其關(guān)聯(lián)的對象的DTO都一并返回呢?

如果這樣的話,必然導(dǎo)致數(shù)據(jù)傳輸量的大增,對于分布式應(yīng)用來說,由于涉及數(shù)據(jù)在網(wǎng)絡(luò)上的傳輸、序列化和反序列化,這種設(shè)計更不可接受。如果getUser除了要返回User的基本信息外,還需要返回一個AccountId、AccountName、RegionId、RegionName,那么,請把這些屬性定義到UserInfo中,把一個“立體”的對象樹“壓扁”成一個“扁平的二維對象”,筆者目前參與的項(xiàng)目是一個分布式系統(tǒng),該系統(tǒng)不管三七二十一,把一個對象的所有關(guān)聯(lián)對象都轉(zhuǎn)換為相同結(jié)構(gòu)的DTO對象樹并返回,導(dǎo)致性能非常的慢。

七、DO與PO的區(qū)別

DO和PO在絕大部分情況下是一一對應(yīng)的,PO是只含有g(shù)et/set方法的POJO,但某些場景還是能反映出兩者在概念上存在本質(zhì)的區(qū)別:

  • DO在某些場景下不需要進(jìn)行顯式的持久化,例如利用策略模式設(shè)計的商品折扣策略,會衍生出折扣策略的接口和不同折扣策略實(shí)現(xiàn)類,這些折扣策略實(shí)現(xiàn)類可以算是DO,但它們只駐留在靜態(tài)內(nèi)存,不需要持久化到持久層,因此,這類DO是不存在對應(yīng)的PO的。

  • 同樣的道理,某些場景下,PO也沒有對應(yīng)的DO,例如老師Teacher和學(xué)生Student存在多對多的關(guān)系,在關(guān)系數(shù)據(jù)庫中,這種關(guān)系需要表現(xiàn)為一個中間表,也就對應(yīng)有一個TeacherAndStudentPO的PO,但這個PO在業(yè)務(wù)領(lǐng)域沒有任何現(xiàn)實(shí)的意義,它完全不能與任何DO對應(yīng)上。這里要特別聲明,并不是所有多對多關(guān)系都沒有業(yè)務(wù)含義,這跟具體業(yè)務(wù)場景有關(guān),例如:兩個PO之間的關(guān)系會影響具體業(yè)務(wù),并且這種關(guān)系存在多種類型,那么這種多對多關(guān)系也應(yīng)該表現(xiàn)為一個DO,又如:“角色”與“資源”之間存在多對多關(guān)系,而這種關(guān)系很明顯會表現(xiàn)為一個DO——“權(quán)限”。

  • 某些情況下,為了某種持久化策略或者性能的考慮,一個PO可能對應(yīng)多個DO,反之亦然。例如客戶Customer有其聯(lián)系信息Contacts,這里是兩個一對一關(guān)系的DO,但可能出于性能的考慮(極端情況,權(quán)作舉例),為了減少數(shù)據(jù)庫的連接查詢操作,把Customer和Contacts兩個DO數(shù)據(jù)合并到一張數(shù)據(jù)表中。反過來,如果一本圖書Book,有一個屬性是封面cover,但該屬性是一副圖片的二進(jìn)制數(shù)據(jù),而某些查詢操作不希望把cover一并加載,從而減輕磁盤IO開銷,同時假設(shè)ORM框架不支持屬性級別的延遲加載,那么就需要考慮把cover獨(dú)立到一張數(shù)據(jù)表中去,這樣就形成一個DO對應(yīng)對個PO的情況。

  • PO的某些屬性值對于DO沒有任何意義,這些屬性值可能是為了解決某些持久化策略而存在的數(shù)據(jù),例如為了實(shí)現(xiàn)“樂觀鎖”,PO存在一個version的屬性,這個version對于DO來說是沒有任何業(yè)務(wù)意義的,它不應(yīng)該在DO中存在。同理,DO中也可能存在不需要持久化的屬性。

八、DO與PO的應(yīng)用

  • 由于ORM框架的功能非常強(qiáng)大而大行其道,而且JavaEE也推出了JPA規(guī)范,現(xiàn)在的業(yè)務(wù)應(yīng)用開發(fā),基本上不需要區(qū)分DO與PO,PO完全可以通過JPA,Hibernate Annotations/hbm隱藏在DO之中。雖然如此,但有些問題我們還必須注意:

  • 對于DO中不需要持久化的屬性,需要通過ORM顯式的聲明,如:在JPA中,可以利用@Transient聲明。

  • 對于PO中為了某種持久化策略而存在的屬性,例如version,由于DO、PO合并了,必須在DO中聲明,但由于這個屬性對DO是沒有任何業(yè)務(wù)意義的,需要讓該屬性對外隱藏起來,最常見的做法是把該屬性的get/set方法私有化,甚至不提供get/set方法,但對于Hibernate來說,這需要特別注意,由于Hibernate從數(shù)據(jù)庫讀取數(shù)據(jù)轉(zhuǎn)換為DO時,是利用反射機(jī)制先調(diào)用DO的空參數(shù)構(gòu)造函數(shù)構(gòu)造DO實(shí)例,然后再利用JavaBean的規(guī)范反射出set方法來為每個屬性設(shè)值,如果不顯式聲明set方法,或把set方法設(shè)置為private,都會導(dǎo)致Hibernate無法初始化DO,從而出現(xiàn)運(yùn)行時異常,可行的做法是把屬性的set方法設(shè)置為protected。

  • 對于一個DO對應(yīng)多個PO,或者一個PO對應(yīng)多個DO的場景,以及屬性級別的延遲加載,Hibernate都提供了很好的支持,請參考Hibnate的相關(guān)資料。

到目前為止,相信大家都已經(jīng)比較清晰的了解VO、DTO、DO、PO的概念、區(qū)別和實(shí)際應(yīng)用了。通過上面的詳細(xì)分析,我們還可以總結(jié)出一個原則:分析設(shè)計層面和實(shí)現(xiàn)層面完全是兩個獨(dú)立的層面,即使實(shí)現(xiàn)層面通過某種技術(shù)手段可以把兩個完全獨(dú)立的概念合二為一,在分析設(shè)計層面,我們?nèi)匀唬ㄖ辽僭陬^腦中)需要把概念上獨(dú)立的東西清晰的區(qū)分開來,這個原則對于做好分析設(shè)計非常重要(工具越先進(jìn),往往會讓我們越麻木)。

最后
歡迎大家一起交流,喜歡文章記得點(diǎn)個贊喲,感謝支持!

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

當(dāng)前題目:一遍文章搞清楚VO、DTO、DO、PO的概念、區(qū)別-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://aaarwkj.com/article2/deddic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、網(wǎng)站營銷網(wǎng)站導(dǎo)航、搜索引擎優(yōu)化、電子商務(wù)、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
农村精品少妇久久久久久| 国产欧美高清在线观看视频| 亚洲国产日韩在线精品| 久久人妻一区二区三区免费密臀| 日本免费精品人成视频| 国产精品一区二区三区熟女| 日本一区二区不卡二区| 高清国产在线播放91| 日本韩国国语对白一区二区三区| 老湿机午夜十分钟视频| av中文字幕一二三区| 91麻豆亚洲国产成人久久| 自拍日韩亚洲一区在线| 久久成人激情免费视频| 蜜桃av噜噜一区二区三| 中文字幕日韩欧美一区| 在线午夜免费视频观看| av天堂午夜精品蜜臀| 欧美精品日本一区二区| 国产亚洲一区二区三区日韩| 色综合久久婷婷色综合网| 精品国产一区二区三区av在线| 亚洲一区二区三区视频在线观看| 日本亚洲美丽少妇天堂| 亚洲性感美女男人的天堂| 欧美日韩亚洲综合国产人| 亚州中文字幕久久一区| 偷拍一区二区三区四区| 黑人巨大欧美一区二区| 和富婆啪啪一区二区免费看| 午夜福利片免费在线观看| 日韩黄片免费观看大全| 美女诱惑福利视频久久久| 清纯美女爱爱高潮av| 亚洲精品国产精品乱码不卞| 无套内谢少妇高朝毛片| 人妻av在线中文字幕| 18岁以下禁看视频网站| 亚洲av成人一区二区三区| 福利在线午夜绝顶三级| 国产黄片a三级久久久久久|