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