EJB設計模式之Data Transfer Object (轉)

worldblog發表於2007-12-12
EJB設計模式之Data Transfer Object (轉)[@more@]Data Traner

在一箇中的客戶端層需要一種嚮往返
傳輸大塊(bulk)資料的方法。

客戶端怎樣能和伺服器大塊資料而無需多個細粒
度呢?

在一個分散式應用中,客戶端和伺服器互動通常可能
有兩個原因。第一個是從伺服器上讀取一些資料來顯
示;第二個是透過建立,,刪除資料來改變服務
器上的資料。在一個ejb環境,這些型別的操作通常
涉及和客戶端(,applet,等等)和一個session
bean,entity bean,或message-driven bean交換資料。

當巨大數量的資料需要被交換,這可以透過兩種方法
達到:1。裝載許多引數到一個方法呼叫(當更新服務
器上的資料),或用2。許多細粒度呼叫從伺服器取到
資料(當客戶端需要從伺服器讀取資料)。當處理大量
引數時前一種方法將迅速失去控制,而後一種方法將
是殺手。

想象一下當客戶端UI需要顯示伺服器上的一個屬性的
集合的情境;這些屬性存在於一個entity bean中或
可透過一個session bean存取。客戶端能得到它所需
要的資料的一個方法是多個對伺服器的細粒度的
呼叫,如圖2.1所示。

這種方法的問題是每個對伺服器的呼叫是一個網路呼叫,
需要對返回值序列化和反序列化,當ejb伺服器截獲對
伺服器的呼叫並完成事務和性檢查時阻塞了客戶端,
並且這時當然對屬性的接受未知。更進一步,如果客戶端
沒有使用 Transaction client-demarcated事務,
每個方法呼叫可能實際上在它自己的分離的事務中執行。

用這種形式執行多個網路呼叫將導致嚴重的效能下降。需要
一個更好的替代方法,該方法允許客戶端在一個大塊(bulk)
呼叫中得到所有需要的資料。

綜上所述:

建立叫做data transfer object的普通Java類,
在一work transportable(跳躍) bundle
(扎,束)中包含和封裝大塊(bulk)資料。

一個data transfer object是一個普通可序列化
的java類,它代表一些伺服器端資料的快照(snapshot),
如下面例子:
import java.io.Serializable;

public class SomeDTO implements Serializable{
   private long attribute1;
   private String attribute2;
   private String attribute3;
   

   ...

   public long getAttribute1();
   public String getAttribute2();
   public String getAttribute3();
   ...

}//SomeSTO

在一個分散式系統中可以把Data transfer object用作
讀取操作和更新操作。當一個客戶端需要更新伺服器上
的一些資料時,它能建立一個封裝所有伺服器需要去更新
的資訊的DTO,並傳到伺服器(通常是一個session facade)
去處理。當然,它也能用成萬億的細粒度引數來傳輸資料
到伺服器,不過這是一個非常脆弱的方法。每當一個引數
需要去被增加或刪除,方法簽名需要改變。透過用DTO封裝
方法引數,變化只被孤立到DTO自己身上。

明顯需要data transfer object的地方是讀操作。當一個
客戶端需要讀一些伺服器端資料(為了傳遞到客戶端UI目的),
客戶端能透過在data transfer object的形式封裝資料來
在一個大塊(bulk)網路呼叫中得到所有資料。

使用先前的例子,伺服器端ejb將建立一個DTO(如圖2.2所示),
並用客戶端需要的屬性傳輸它。這資料將用一個大塊返回值
(data transfer object)返回到客戶端。data transfer
object基本上是一個“信封”,用來在系統的各層間
傳輸任何型別的資料。

   
當使用data transfer object時,開發者面對的一個
常見的問題是:用什麼粒度設計它們。也就是說,你怎
樣選擇用DTO封裝多少資料?你怎樣決定是否需要DTO?
作為首要的在客戶端和伺服器間交換的方法,data
transfer object建立了分離客戶端開發者和伺服器
開發者的介面。在一個專案的開始階段,客戶端和伺服器
開發者需要在決定使用什麼ejb interface的同時決定
data transfer object的設計。不管這個需要,因為
開發者通常不完全懂得什麼資料單元應該在客戶端和伺服器
之間傳輸,所以在專案開始階段設計data transfer object
是很困難的。

開始設計data transfer object的簡單方法是作為伺服器端
entity bean的複製(或領域),如ain Data Transfer
Object所述。設計Domain Data Transfer Object很簡單,
因為專案小組通常有專案可以初期使用的好的領域模型。因此,
把Domain DTO作為客戶端和伺服器之間的交換能讓小組啟動和
執行得更快。


終極的,客戶端和伺服器之間交換的資料應該設計得去滿足
客戶端的需要。因此,當專案進行並且客戶端的需要滿足了,
Domain Data Transfer Object作為交換單元經常變得難用,
太過於粗粒度以至於無法滿足客戶端的細粒度需要。一個客戶
端可能需要存取沒有被封裝在任何Domain Data Transfer
Object中的資料。在這一點上,開發者可以設計custome Data
Transfer Object,就是說,封裝任意資料集的Data Transfer
Object,完全被客戶端的特定需求所。

這兩種設計paradigm的區別會對整個應用的設計產生顯著
影響。雖然它們代表自相矛盾的方法,他們可以通常在
任何J2EE應用中共生。

當決定何處放置建立和消耗Data Transfer Object的邏輯
時,Data Transfer Object Factory模式描繪了一個可行的
並且可維護的解決方案。一個和跨層(DTO,HashMap,RowSet)
的任何種類的資料傳輸一起發生的事件是:當資料到達客戶端
時,它有潛在的不是最新的可能性。Version Number模式
能解決這個問題。

相關模式
State Holder
value Object
Details Object

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-991686/,如需轉載,請註明出處,否則將追究法律責任。

相關文章