dto与dto相互转换_在DTO上
dto與dto相互轉(zhuǎn)換
通常使用DTO或數(shù)據(jù)傳輸對象 。 什么不是s? 眾所周知,它們源自DDD(域驅(qū)動設(shè)計)。 在那里很有意義–域?qū)ο缶哂袪顟B(tài),身份和業(yè)務(wù)邏輯,而DTO僅具有狀態(tài)。但是,當(dāng)今許多項目正在使用貧血數(shù)據(jù)模型方法( 我認(rèn)為 ),并且仍在使用DTO。 每當(dāng)對象“離開”服務(wù)層或“離開”系統(tǒng)時(通過Web服務(wù),rmi等),都將使用它們。 有三種方法:
- 每個實體至少具有一個對應(yīng)的DTO。 對于視圖層中的不同方案,通常不止一個。 在列表中顯示用戶時,您會有一個DTO,而在“用戶詳細(xì)信息”窗口中顯示時,則需要一個擴(kuò)展的DTO。 我不贊成這種方法,因為在很多情況下,DTO和域結(jié)構(gòu)具有完全相同的結(jié)構(gòu),因此,存在很多重復(fù)的代碼+冗余映射。 另一件事是多個DTO的可變性。 即使它們與實體不同,它們在一個或兩個字段之間也彼此不同。 為什么重復(fù)是一件壞事? 因為要在兩個地方進(jìn)行更改,所以當(dāng)數(shù)據(jù)通過多個對象時,很難跟蹤問題,并且因為它是重復(fù)的。 在同一項目中復(fù)制和粘貼是一種罪過。
- 僅當(dāng)DTO的結(jié)構(gòu)與實體的結(jié)構(gòu)明顯不同時才創(chuàng)建DTO。 在所有其他情況下,都使用實體本身。 您不希望顯示某些字段的情況(尤其是在通過Web服務(wù)公開給第三方的情況下)存在,但并不常見。 有時可以通過序列化機(jī)制來處理(例如,將其標(biāo)記為@JsonIgnore或@XmlTransient) ,但在其他情況下,結(jié)構(gòu)則有所不同。 在這些情況下,應(yīng)有DTO。 例如,您有一個User和UserDetails,其中UserDetails保存詳細(xì)信息+當(dāng)前登錄用戶與給定用戶的關(guān)系。 后者與實體無關(guān),因此您創(chuàng)建一個DTO。 但是,對于DirectMessage,在數(shù)據(jù)庫和UI中都具有發(fā)件人,收件人,文本和日期時間。 無需DTO。
使用此方法的一個警告(以及下一個警告)。 貧血的實體通常帶有ORM(對于Java,則為JPA)。 每當(dāng)它們退出服務(wù)層時,由于需要開放會話的惰性集合,它們可能無效。 您在這里有兩個選擇:
- 使用OpenSessionInView / OpenEntityManagerInView –這樣,會話將保持打開狀態(tài),直到您準(zhǔn)備好響應(yīng)為止。 這很容易配置,但不是我的首選-它以一種微妙的方式違反了層邊界,這有時會導(dǎo)致問題,特別是對于新手開發(fā)人員
- 不要使用惰性集合。 不需要延遲收集。 如果他們應(yīng)該保留一小部分項目(例如,用戶角色列表),或者如果數(shù)據(jù)可能會增長而使用查詢,要么讓他們渴望。 是的,無論如何您都不會顯示1000條記錄,您必須對其進(jìn)行分頁。 如果沒有惰性關(guān)聯(lián)(默認(rèn)情況下@@ ToOne渴望),則在關(guān)閉會話時不會有無效的對象
- 完全不使用DTO。 沒有明顯變化的結(jié)構(gòu),請盡快應(yīng)用。 對于較小的項目,這通常是一個好方法。 上面提到的所有內(nèi)容都適用于此。
因此,我首選的方法是“ 中間方法 ”。 但是在每種情況下都需要考慮很多因素,這可能不適用于規(guī)模較大和/或經(jīng)驗較少的團(tuán)隊。 因此,應(yīng)該選擇兩個“極端”之一。 由于還需要考慮“無DTO”方法-做@Transient是什么,惰性集合如何影響流量等,因此通常選擇“所有DTO”。 但是,盡管這似乎是最安全的方法,但仍有很多陷阱。
首先,您如何從DTO映射到實體,反之亦然? 三種選擇:
- 專用的映射器類
- 構(gòu)造函數(shù)– DTO構(gòu)造函數(shù)接受實體并填充自身,反之亦然(記住也要提供默認(rèn)的構(gòu)造函數(shù))
- 聲明性映射(例如Dozer )。 這實際上與第一個選項相同–它外部化了映射。 它甚至可以與專用的映射器類一起使用
- 串聯(lián)映射它們(必要時)。 這可能會生成無法維護(hù)的代碼,因此不是首選
我更喜歡構(gòu)造方法,至少是因為創(chuàng)建的類更少。 但是它們本質(zhì)上是相同的(DTO并不以封裝聞名,因此您的所有屬性無論如何都公開)。 這是使用DTO和兩種“映射”方法時的準(zhǔn)則列表:
- 不要生成過多的冗余代碼。 如果兩種情況需要稍微不同的DTO,請重用。 無需為一兩個字段之間的差異創(chuàng)建新的DTO
- 不要將表示邏輯放在映射器/構(gòu)造函數(shù)中。 例如,如果( entity.isActive() ) dto.setStatus(“ Active”); 這應(yīng)該在視圖層中發(fā)生
- 不要將實體與DTO一起偷偷摸摸。 DTO不應(yīng)具有作為實體的成員。 通常,不應(yīng)在服務(wù)層之外使用實體(這有點極端,但是如果我們在所有地方都使用DTO,則應(yīng)該保持一致并堅持這種做法)
- 不要在控制器中使用mappers / entity-to-dto構(gòu)造函數(shù),而在服務(wù)層中使用它們。 首先使用DTO的原因是實體可能是ORM綁定的,并且它們可能在會話外部(即服務(wù)層外部)無效。
- 如果使用映射器,則首選靜態(tài)映射器方法。 映射器沒有狀態(tài),因此不需要實例化它們。 (而且不必嘲笑,包裝等)。
- 如果使用映射器,則無需為每個實體(+多個DTO)使用單獨(dú)的映射器。 可以將相關(guān)實體分組在一個映射器中。 例如Company , CompanyProfile , CompanySubsidiary可以使用相同的映射器類
只需確保在項目開始時就做出所有這些決定,然后確定哪種情況適用于您的方案(團(tuán)隊規(guī)模和經(jīng)驗,項目規(guī)模,領(lǐng)域復(fù)雜性)。
參考: 在的DTO從我們JCG伙伴 Bozho在Bozho的科技博客 。
相關(guān)文章 :
- Spring和AspectJ的領(lǐng)域驅(qū)動設(shè)計
- 在域驅(qū)動設(shè)計中使用狀態(tài)模式
- ORM問題
- 什么是依賴倒置? 是IoC嗎?
- 框架使開發(fā)人員愚蠢嗎?
- 每個程序員都應(yīng)該知道的事情
- JDK中的設(shè)計模式
- Java最佳實踐
翻譯自: https://www.javacodegeeks.com/2011/09/on-dtos.html
dto與dto相互轉(zhuǎn)換
總結(jié)
以上是生活随笔為你收集整理的dto与dto相互转换_在DTO上的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux安装服务器(linux安装 服
- 下一篇: Lambdas中的例外:有点混乱的优雅解