分布式應(yīng)用架構(gòu)中的數(shù)據(jù)傳輸對象(DTO)
Written by: Rickie Lee
Dec. 1, 2004
在分布式架構(gòu)中,相關(guān)層在物理部署上實現(xiàn)分離,通過網(wǎng)絡(luò)或跨進程調(diào)用遠程對象或服務(wù)。在這種分布式架構(gòu)中,需要定義有效的數(shù)據(jù)傳輸對象(Data Transfer Object, DTO)來實現(xiàn)層與層之間的數(shù)據(jù)傳輸。
因為遠程調(diào)用需要跨越網(wǎng)絡(luò)或進程,因此會比較慢。通過使用DTO,在單一遠程調(diào)用中傳輸更多的數(shù)據(jù)信息,減少遠程調(diào)用的次數(shù),提高分布式調(diào)用的性能。
下面分析一些比較常用的數(shù)據(jù)傳輸對象(DTO):
1.DataSet
DataSet是緩存在內(nèi)存中的表,它是從關(guān)系數(shù)據(jù)庫或 XML 文檔中獲得的??梢允褂?/span> DataSet來表示從數(shù)據(jù)庫中檢索到的業(yè)務(wù)實體數(shù)據(jù),然后可以在層與層之間使用DataSet來傳遞數(shù)據(jù)。Microsoft提供的范例Duwamish 7.0中使用大量的DataSet來實現(xiàn)層與層之間的數(shù)據(jù)傳遞,如Presentation層與BusinessFacade層等等。
優(yōu)點:(1)DataSet類由.Net Framework內(nèi)置實現(xiàn),不必編寫和維護額外的類。(2)DataSet可以與Windows Form和Web Form的內(nèi)置控件直接交互,如DataGrid等。(3)DataSet支持序列化XML,不僅包括內(nèi)容序列化,還包括Schema。(4)非連接的數(shù)據(jù)模式。(5)DataSet 可以包含數(shù)據(jù)的集合,能夠表示復(fù)雜的數(shù)據(jù)關(guān)系。
缺點:(1)互操作性問題,因為DataSet類是ADO.NET提供的,因此要求Client端在.Net Framework平臺上運行。(2)陳舊的數(shù)據(jù),因為DataSet包含的數(shù)據(jù)是Database的快照,如果Database的數(shù)據(jù)經(jīng)常改變,則不推薦采用DataSet。(3)依賴Database schema,訪問DataSet中數(shù)據(jù)時,要求顯式指定字段類型和數(shù)據(jù)表之間的關(guān)系,如果Database schema發(fā)生變化,相應(yīng)的code也要變化。要訪問 DataSet 中的表,客戶端代碼必須使用整數(shù)索引生成器或字符串索引生成器來索引 DataTable 集合。要訪問特定列,必須使用列編號或列名稱索引 DataColumn 集合。(4)缺乏類型安全,當(dāng)從DataSet中取值時,需要顯式指定要轉(zhuǎn)換的數(shù)據(jù)類型,這樣容易產(chǎn)生錯誤。(5)性能問題。實例化和封送處理 DataSet 會增加運行時負擔(dān)。
2.有類型的DataSet
有類型的DataSet是從 ADO.NET DataSet 類繼承而來的類,包含具有嚴(yán)格類型的方法、屬性和類型定義以公開 DataSet 中的數(shù)據(jù)和元數(shù)據(jù)的類。
優(yōu)點:除了上述DataSet的部分優(yōu)點外,有類型的 DataSet 還提供了數(shù)據(jù)驗證支持(在編譯時進行類型檢查,無效的表名稱和列名稱將在編譯時而不是在運行時檢測),并且簡化代碼的編寫,提高代碼的可讀性。
缺點:(1)具有DataSet的大部分缺點,除了提供類型安全。(2)另外,需要編寫或維護用來描述typed interface的XML Schema,不過幸好VS.Net IDE提供工具支持。(3)部署問題。必須將包含有類型的 DataSet 類的程序集部署到使用業(yè)務(wù)實體的所有層。(4)可擴展性問題。如果修改了數(shù)據(jù)庫架構(gòu),則可能需要重新生成有類型的 DataSet 類以支持新架構(gòu)。重新生成過程將不會保留在有類型的 DataSet 類中實現(xiàn)的任何自定義代碼。必須將包含有類型的 DataSet 類的程序集重新部署到所有客戶端應(yīng)用程序中。
有類型的方法和屬性的提供使得使用有類型的 DataSet 比使用通用 DataSet 更方便。使用有類型的 DataSet 時,IntelliSense 將可用。有類型的 DataSet 的實例化和封送處理性能與通用 DataSet 基本相同。
3.自定義業(yè)務(wù)實體(Business Entity)
這是一種自定義類,用于表示各種業(yè)務(wù)實體類型??梢远x保存業(yè)務(wù)實體數(shù)據(jù)的字段,并定義將此數(shù)據(jù)向應(yīng)用程序各層中公開的屬性(getter/setter),或者進一步使用在該類中定義的字段來定義方法以封裝簡單的業(yè)務(wù)邏輯。
應(yīng)當(dāng)封裝應(yīng)用程序的功能的核心業(yè)務(wù)實體,而不是為每個表定義單獨的業(yè)務(wù)實體。
優(yōu)點:(1)可維護性,更改架構(gòu)一般不會影響數(shù)據(jù)訪問邏輯組件方法簽名。(2)相對DataSet而言,有更好的性能。(3)編譯期間提供類型安全檢測。(4)代碼易讀。要訪問自定義實體類中的數(shù)據(jù),可以使用有類型的方法和屬性。(5)自定義實體可以包含方法以封裝簡單的業(yè)務(wù)規(guī)則。(6)本地化驗證。自定義實體類可以在其屬性存取器(getter/setter)中執(zhí)行簡單的驗證測試以檢測無效的業(yè)務(wù)實體數(shù)據(jù)。(7)專用字段??梢噪[藏不希望向調(diào)用程序公開的信息。
缺點:(1)需要編寫并維護自定義DTO類。(2)自定義實體表示的是單個業(yè)務(wù)實體,而不是一個業(yè)務(wù)實體集合。要保存多個業(yè)務(wù)實體,調(diào)用應(yīng)用程序必須創(chuàng)建一個數(shù)組或一個 .NET 集合。(3)必須在自定義實體中實現(xiàn)自己的序列化機制??梢允褂脤傩詠砜刂茖嶓w組件的序列化方式,也可以通過實現(xiàn) ISerializable 接口來控制自己的序列化。(4)部署問題。必須在所有物理層部署包含自定義實體的程序集。(5)可擴展性問題。如果修改了數(shù)據(jù)庫架構(gòu),則可能需要修改自定義實體類并重新部署程序集。
4.簡單標(biāo)量參數(shù)列表
根據(jù)需要傳入的參數(shù),傳入一系列簡單的標(biāo)量值。
優(yōu)點:(1)標(biāo)量值本身支持序列化。(2)內(nèi)存使用效率高,標(biāo)量值只傳遞實際調(diào)用需要的數(shù)據(jù)。(3)更高的性能。(4)最明顯的特點是簡單方便。
缺點:(1)緊密耦合與維護。架構(gòu)的更改可能需要修改方法簽名,這會影響調(diào)用代碼。(2)有可能存在進行多次單獨的方法調(diào)用,這在分布式環(huán)境中會給性能帶來很大影響。(3)難以表達復(fù)雜的數(shù)據(jù)關(guān)系。
當(dāng)然,在實際的分布式應(yīng)用系統(tǒng)中,會根據(jù)實際情況的要求,使用不同的DTO對象。
下面通過描述簡單的分布式應(yīng)用架構(gòu)模型設(shè)計,來演示DTO對象在層與層之間的數(shù)據(jù)傳遞和交互: