Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1532188
  • 博文数量: 3500
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 43870
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-03 20:31
文章分类

全部博文(3500)

文章存档

2008年(3500)

我的朋友

分类:

2008-05-04 20:57:47

一起学习
本文参考了SUN blueprint 模式站点中有关 Value Object(值对象)阐述[英文原文],向大家介绍一种 用粗粒度的数据对象传输 来 提高远程传输效率 的EJB配套 设计模式.该模式有效减轻了 以往翻复的 远程调用,减少了 网络的传输...... 值对象 是使用 粗粒度的数据对象传输 来 提高远程传输效率。 实体 Bean 有时总是会有一大堆 属性变量,比如 用户的联系信息(城市,邮政编码,电话,Email等等),假设一下,如果 用户信息有15个属性,那需要声明 15个 getXXX 方法去 获取这些属性,当所有的用户信息被读取的时候,总共需要在CustomerEJB 中调用15个方法,这样加重了网络传输负担 和 容器的负载。 一种解决的方法是使用粗粒度数据对象来代表这些信息,我们把EJB 中的属性变量整和到一个 数据对象ContactInformation 中,之后该对象序列化后被传输到客户端调用,在那里被逆序列化后被客户解读,可以看出后来的解读过程是客户端对本地对象的操作,而不是对远程EJB 的操作,所以没有占用服务器的工作,减少了资源利用。 下图是操作EJB的属性变量,在使用值对象前后的对比 从图中我们可以看出后者 在读取 city, state zipcode等细粒度的变量时没有直接 操作 远程的 EJB ,而是一次性请求 EJB返回 一个 粗粒度的 CustomInfo对象 ,在本地 解析该 对象 返回细粒度的变量。这就是所谓的 值对象模式. 下图就是 值对象的结构图 : 需要注意的是 值对象 虽然是商业逻辑对象,但他只包含了如何解析 值对象 方法,如何构成这些信息 是EJB的工作. 应用值对象,我们应注意: 1.值对象 包含 一组私有变量 和一些获取这些变量相应的方法,他必须是可序列化的(要实现Serializable接口或者 提供方法 可以把变量 转化成可序列化 的对象,比如String),这样 EJB才能把它序列化。 2.值对象是只读的,他只是用于读取EJB的属性变量,我们不可能对他操作来改变 实体 EJB.不过我们可以创建一个新的值对象 ,把他作为远程EJB对象的一个创建参数 来更改 实体EJB的属性变量.这样做其实是把所有的改动一起传递给EJB,而不是象以往那样多次的调用远程方法来更改每一个属性. 3.考虑避免采用 过大的值对象 ,值对象本来就是为了减轻网络传输负担,所以需要 拆分 大的值对象. 4.在EJB2.0规范下使用值对象。在EJB2.0中 提出了依赖性值类(dependent value class),如果把实体Bean 看成是 数据库中一条(行)数据的话 ,依赖性值类就代表了一行数据 的 其中几列,这样 一个实体Bean 就可以表示成 几个 值对象,并且在 CMP 实体Bean 中需要 提供accessor (例如 getXXX) 和 mutator (例如 setXXX) 这样的方法来 读取和改写 值对象。很明显,accessor(getXXX)返回的是值对象 ,mutator(setXXX)把值对象作为参数 传入来改写 相应的数据. 范例代码: 我们看一下 在SUN的 java pet store范例中 做 实体 EJB数据 update 的 相应代码: 当从 一个 更新帐号信息的 jsp (editaccount.jsp) 提交了 更新请求 ,该请求由 web层的 AccountHandler 处理: public class AccountHandler extends RequestHandlerSupport { public EStoreEvent processRequest(HttpServletRequest request) throws EStoreEventException { // ... String action = request.getParameter("action"); if (action == null) { return null; } else if (action.equals("createAccount")) { return createNewAccountEvent(request); } else if (action.equals("updateAccount")) { return createUpdateAccountEvent(request); // ... } } createUpdateAccountEvent来把提交的信息封装成 contactInformation 值对象,并传送给 下一个处理 private EStoreEvent createUpdateAccountEvent(HttpServletRequest request) { // ... AccountEvent event = new AccountEvent(); // ... ContactInformation contactInformation = extractContactInformation(request); // ... event.setInfo(userId, contactInformation, explicitInformation); // ...then Ejb will do with the contactInformation } } EJB 层的 AccountHandler 来处理 更新操作,注意 CustomerEJB.changeContactInformation() 的参数 是 ContactInformation ,它由 ae.getContactInformation() 得到. public class AccountHandler extends StateHandlerSupport { public void perform(EStoreEvent event) throws EStoreEventException { AccountEvent ae = (AccountEvent)event; switch (ae.getActionType()) { // ... case AccountEvent.UPDATE_ACCOUNT: { try { CustomerHome home = EJBUtil.getCustomerHome(); Customer cust = home.create(); cust.changeContactInformation(ae.getContactInformation(), ae.getUserId()); // ... 可以看出 以前 多次的 setxxx 的远程调用 被 现在一次 changeContactInformation() 替代了. (图片源自java.sun.com) 下载本文示例代码


Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式Value Object(值对象) 模式
阅读(385) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~