在一个ejb系统中的客户端层需要一种向服务器往返
传输大块(bulk)数据的方法。
客户端怎样能和服务器交换大块数据而无需多个细粒
度网络调用呢?
在一个分布式应用中,客户端和服务器交互通常可能
有两个原因。第一个是从服务器上读取一些数据来显
示;第二个是通过创建,更新,删除数据来改变服务
器上的数据。在一个ejb环境,这些类型的操作通常
涉及和客户端(servlet,applet,等等)和一个session
bean,entity bean,或message-driven bean交换数据。
当巨大数量的数据需要被交换,这可以通过两种方法
达到:1。装载许多参数到一个方法调用(当更新服务
器上的数据),或用2。许多细粒度调用从服务器取到
数据(当客户端需要从服务器读取数据)。当处理大量
参数时前一种方法将迅速失去控制,而后一种方法将
是性能杀手。
想象一下当客户端UI需要显示服务器上的一个属性的
集合的情境;这些属性存在于一个entity bean中或
可通过一个session bean存取。客户端能得到它所需
要的数据的一个方法是执行多个对服务器的细粒度的
调用,如图2.1所示。
这种方法的问题是每个对服务器的调用是一个网络调用,
需要对返回值序列化和反序列化,当ejb服务器截获对
服务器的调用并完成事务和安全性检查时阻塞了客户端,
并且这时当然对属性的接受未知。更进一步,如果客户端
没有使用Java Transaction API client-demarcated事务,
每个方法调用可能实际上在它自己的分离的事务中执行。
用这种形式执行多个网络调用将导致严重的性能下降。需要
一个更好的替代方法,该方法允许客户端在一个大块(bulk)
调用中得到所有需要的数据。
综上所述:
创建叫做data transfer object的普通Java类,
在一个network 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基本上是一个“信封”,用来在J2EE系统的各层间
传输任何类型的数据。
当使用data transfer object时,开发者面对的一个
常见的问题是:用什么粒度设计它们。也就是说,你怎
样选择用DTO封装多少数据?你怎样决定是否需要DTO?
作为首要的在客户端和服务器间交换的方法,data
transfer object建立了分离客户端开发者和服务器
上一页 下一页






