java中DTO與DAO的問題

2021-04-13 00:58:15 字數 4454 閱讀 6271

什麼是dto

2007-02-09 15:42

您正在設計乙個分布式應用程式,為了滿足單個客戶端請求,您發現自己對乙個遠端介面發出了多個呼叫,而這些呼叫所增加的響應時間超出了可接受的程度。 

問題

如何保留過程呼叫介面的簡單語義,而不受遠端通訊固有的滯後時間問題的影響?

在與遠端物件通訊時,請考慮下列需要權衡的因素:

"遠端呼叫(那些必須跨越網路的呼叫)速度緩慢。雖然許多遠端呼叫框架可以隱藏進行遠端呼叫的複雜性,但是它們不能消除發生通訊所需的步驟。例如,必須先找到遠端物件位置,而且建立與遠端計算機的連線,然後才能將資料序列化為位元組流,然後可能進行加密,最後才能將其傳輸到遠端計算機。 

"在考慮網路效能時,必須同時考慮滯後時間和吞吐量。簡單地說,"滯後時間"描述了資料的首位元組到達目的地之前所經過的時間。"吞吐量"描述了在某個時間段(例如 1 秒)內通過網路傳送的資料位元組數。在基於 ip 路由的現代網路(例如 internet)中,滯後時間可以是比吞吐量更大的因素。這意味著,傳輸 10 位元組資料所用的時間可能幾乎等於傳輸 1,000 位元組資料所用的時間。在使用無連線協議(如 http)時,此效果尤其明顯。通常,網路速度越快可以使吞吐量得以增加,但是,要減少滯後時間則會更加困難。 

"在設計物件介面時,好的做法是將大量資訊隱藏在物件內,並提供一組細粒度方法來訪問和操作該資訊。"細粒度"意味著每個方法都應該負責單個的、相當小的和基本的功能單位。此方法簡化了程式設計,並提供了對物件內部的更佳抽象,從而增加了重用的可能性。必須根據以下事實對此進行平衡取捨:使用較細粒度的方法意味著需要呼叫更多的方法才能執行高階別的任務。通常,在同一程序內呼叫方法時,這些額外函式呼叫的開銷是可接受的;但是,在跨程序和網路邊界呼叫這些方法時,開銷可能變得難以接受。 

"避免遠端呼叫中固有的滯後時間問題的最佳方法是進行更少的呼叫,並讓每個呼叫傳遞更多的資料。做到這一點的一種方法是,使用長引數列表來宣告遠端方法。這樣,客戶端就可以在單個呼叫中將更多的資訊傳遞給遠端元件。但是,這樣做會使針對此介面的程式設計容易出錯,因為程式很可能僅按呼叫語句中的位置來呼叫外部方法的引數。例如,如果遠端方法接受 10 個字串引數,則開發人員很容易按錯誤順序傳遞引數。編譯器將無法檢測到這樣的錯誤。

"長引數列表無助於從遠端呼叫向客戶端返回更多的資訊,因為大多數的程式語言將方法呼叫的返回型別限制為單個引數。而巧合的是,在傳輸大多數資料時通常需要返回較多資訊。例如,許多使用者介面傳輸少量的資訊,卻希望返回大量結果資料。 

下圖顯示客戶端應用程式如何進行一系列遠端呼叫以檢索客戶名稱的各個元素。

圖 1:沒有

dto 

的遠端呼叫

dto 允許遠端物件在單個遠端呼叫中將整個客戶名稱返回給客戶端。在此示例中,這樣做將使呼叫次數從 4 次減為 1 次。客戶端進行單個呼叫,然後在本地與 dto 互動,而不用進行多次遠端呼叫(見圖 2)。

圖 2:通過使用

dto 

減少呼叫次數

dto 是一組需要跨程序或網路邊界傳輸的聚合資料的簡單容器。它不應該包含業務邏輯,並將其行為限制為諸如內部一致性檢查和基本驗證之類的活動。注意,不要因實現這些方法而導致 dto 依賴於任何新類。

在設計資料傳輸物件時,您有兩種主要選擇:使用一般集合;或使用顯式的 getter 和 setter 方法建立自定義物件。 

一般集合的優點是,只需要乙個類,就可以在整個應用程式中滿足任何資料傳輸目的。此外,集合類(例如,簡單陣列或哈希圖)內置於幾乎所有語言庫中,因此您根本不必編寫新類的**。對 dto 使用集合物件的主要缺點是,客戶端必須按位置序號(在簡單陣列的情況下)或元素名稱(在鍵控集合的情況下)訪問集合內的字段。此外,集合儲存的是同一型別(通常是最一般的object型別)的專案,這可以導致在編譯時無法檢測到的微妙但致命的編碼錯誤。

如果為每個 dto 建立自定義類,則可以提供與任何其他物件完全一樣的、客戶端應用程式可訪問的強型別物件,這樣的物件可以提供編譯時檢查,並支援**編輯器功能(如 microsoft® intellisense® 技術)。主要缺點是,如果應用程式發出許多遠端呼叫,則您最終可能必須編寫大量類的**。

許多方法試圖將這兩種方法的優點結合在一起。第一種方法是**生成技術,該技術可以生成脫離現有元資料(如可擴充套件標記語言 (xml) 架構)的自定義 dto 類的源**。第二種方法是提供更強大的集合,儘管它是一般的集合,但它將關係和資料型別資訊與原始資料儲存在一起。microsoft ado.netdataset支援這兩種方法(請參閱在 .net 中使用 dataset 實現 data transfer object)。

有了 dto 類以後,需要用資料填充它。大多數情況下,dto 內的資料來自多個域物件。因為 dto 沒有行為,因此它不能從域物件提取資料。這是對的,因為如果讓 dto 不知道域物件,您就可以在不同的上下文中重用 dto。同樣,您不希望域物件知道 dto,因為這可能意味著更改 dto 將要求更改域邏輯中的**,這將導致大量維護任務。 

最佳的解決方案是使用assembler 模式 [fowler03],該模式可以用業務物件建立 dto 或者相反。

圖 3:使用

assembler 

將資料載入到

dto 中

assembler 的關鍵特徵是 dto 和域物件不相互依賴。這就消除了這兩種物件的相互影響。不利方面是assembler同時依賴於 dto 和域物件。對這些類的任何更改都可能導致必須更改assembler類。

測試考慮事項

dto 是簡單物件,它不應該包含需要測試的任何業務邏輯。但是,您確實需要測試每個 dto 的資料聚合。每個 dto 可能需要測試,也可能不需要,這取決於您的序列化機制。如果序列化是框架的一部分,則只需要測試乙個 dto。如果不是這樣,請使用一般的反射機制,這樣就不需要測試每個 dto 的序列化。

dto 還對遠端函式的可測試性有好處。通過使遠端方法的結果能夠在物件例項中使用,可以輕鬆地將此資料傳遞到測試模組,或將其與所需結果進行比較。 

理想情況下,應該先篩選和驗證從不可靠的**獲得的資料(如來自 web 頁的使用者輸入),然後將其置於 dto 中。通過這樣做,就可以認為 dto 中的資料是相對安全的,從而簡化了將來與 dto 的互動。

接收 dto 的程序和關聯使用者的安全憑據也是值得注意的。dto 通常包含從許多不同**聚集在一起的大量資訊。您是否已授權 dto 的所有使用者訪問 dto 所包含的所有資訊?確保使用者已得到授權的最佳方法是僅使用使用者安全憑據所允許的特定資料填充 dto。努力避免讓 dto 負責自己的安全性。這將增加 dto 對其他類的依賴數,這意味著必須將這些類部署到使用 dto 的所有節點。這還會將安全性功能分散到更多類中,從而增大了安全風險,並對靈活性和可維護性產生負面影響。 

data transfer object 具有下列優缺點:

優點

"減少了遠端呼叫次數。通過在單個遠端呼叫中傳輸更多的資料,應用程式可以減少遠端呼叫次數。

"提高了效能。遠端呼叫可以使應用程式的執行速度大大降低。減少呼叫次數是提高效能的最佳方法之一。在大多數方案中,傳輸大量資料的遠端呼叫所用的時間與僅傳輸少量資料的呼叫所用的時間幾乎相等。 

"隱藏內部情況。在單個呼叫中來回傳遞更多的資料,還可以更有效地將遠端應用程式的內部情況隱藏在粗粒度介面的背後。這就是使用 remote facade 模式 [fowler03] 的主要原因。

"發現業務物件。在一些情況下,定義 dto 有助於發現有意義的業務物件。在建立用作 dto 的自定義類時,您通常會注意到作為一組凝聚性資訊而顯示給使用者或另乙個系統的元素分組。通常,這些分組用作描述應用程式所處理的業務域的物件的有用原型。 

"可測試性。將所有引數封裝到可序列化物件中可以提高可測試性。例如,可以從 xml 檔案中讀取 dto,並呼叫遠端函式以測試它們。同樣,可以輕鬆地將結果再序列化為 xml 格式,並將 xml 文件與所需結果進行比較,而不必建立冗長的比較指令碼。

缺點

"可能需要太多的類。如果選擇了使用強型別的 dto,則可能必須為每個遠端方法建立乙個(如果考慮返回值,則為兩個)dto。即使在粗粒度介面中,這也可能導致大量的類。編寫如此數量的類的**並管理這些類會是很困難的。使用自動**生成可以在一定程度上緩解此問題。

"增加計算量。如果將伺服器上的一種資料格式轉換為可以跨網路傳輸的位元組流,並在客戶端應用程式內轉換回物件格式,可以帶來相當大的開銷。通常,需要將來自多個源的資料聚合到伺服器上的單個 dto 中。要提高通過網路進行遠端呼叫的效率,必須在任一端執行其他計算,才能聚合和序列化資訊。

"增加編碼工作量。可以用一行**完成將引數傳遞到方法的操作。使用 dto 要求例項化新物件,並為每個引數呼叫 setters 和 getters。編寫此**可能是很乏味的。

"remote facade

。data transfer object 模式通常與粗粒度remote facade 聯合使用,以減少遠端呼叫次數。 ""

DAO與DTO的區別

dao data access object資料訪問物件 主要用來封裝對資料庫的訪問。通過它可以把pojo持久化為po,用po組裝出來vo dto dto data transfer object資料傳輸物件 主要用於遠端呼叫等需要大量傳輸物件的地方。比如我們一張表有100個字段,那麼對應的po就有...

DAO和DTO的區別

data access object資料訪問物件 主要用來封裝對資料庫的訪問。通過它可以把pojo持久化為po,用po組裝出來vo dtodata transfer object資料傳輸物件 主要用於遠端呼叫等需要大量傳輸物件的地方。dao 資料訪問物件 用來封裝對資料庫的訪問,通過它可以將資料庫中...

dao和dto的區別

dao data access object的縮寫,即資料訪問物件 主要用來封裝應用對資料庫的訪問。通過它可以把bean持久化為po,用po組裝出來vo dto dto data transfer object的縮寫,即資料傳輸物件 主要用於遠端呼叫等需要大量傳輸物件的地方。比如我們一張表有100個...