您现在的位置: 中国教师站 >> 教师学院 >> 电脑技术 >> 编程技术 >> Java >> 正文

最新EJB设计模式中文版之Session Facade(会话外观)
作者:Siny 文章来源:中国教师站cn-teacher 点击数: 更新时间:2007-4-22 15:12:52

session facade


一个EJB客户端为了完成一个用例需要执行一个商业逻辑。

EJB客户端怎样才能在一个事务(transaction)和一个大批
(bulk)网络调用中执行一个用例的商业逻辑呢?

为了执行一个典型的用例的商业逻辑,多个服务器端对象
(如session或entity bean)通常需要被存取和可能的修
改。问题是session和entity bean的多个细粒度(fine-
grained)调用增加了多次网络调用(而且可能是多个事务
的)的网络开销(overhead),并且导致可维护性差的代码,
因为数据存取和工作流/商业逻辑在客户端之间分散了。

考虑一个在线银行情景,一个servlet接受请求来从一
个账户向另一个账户传输存款,作为一个Web客户端。
在这个情景下(像图1.1所示),一个servlet必须检查
来保证用户是授权了的,从一个银行账户entity bean
取出存款,并且把它存入另外一个银行账户entity bean。

当执行一个entity bean的home和remote interface,
这个方法在重负荷时将无法伸缩(scale),因为整个
情景(scenario)需要至少6个网络调用:3个寻找合适
的entity bean,还有三个实际的传送存款。还有,因为
entity bean是事务性的生物,每个对实体的调用需要
一个分离的服务器端的事务,需要通过应用服务器的
数据存储和维护来和远程实体同步。

更糟的是这个方法无法保证客户的钱的安全性。如果在
存钱时出错了,客户的钱将已经被取出,并且他的钱将
会丢失。用户授权检查,取钱,和存钱完全分离的运行,
并且如果存钱失败,取钱将不会回滚(roll back),结果
是不连续的状态。这里的问题是:当entity bean的方法
被直接调用,每个方法调用是一个分离的工作单元,并且
是一个分离的事务。

一个解决方案是在我们的entity bean中加入额外的逻辑,
来在一个单独的客户调用中完成许多操作。这个解决方案
引入了维护问题,因为我们的entity bean层将不能被应
用到许多不同的方式上。如果我们在每次需要性能增强
时增加应用逻辑到我们的entity bean上时,我们的entity
bean将很快变得臃肿和难于理解,维护和复用。我们有
效的将我们的应用逻辑(动词)和我们的持久化逻辑(名词)
融合起来,但这是差的应用设计。

另一个方法是为我们的客户端划分一个聚合,通过JTA的
大的事务。这将每个entity bean的方法调用工作在一个
相同的事务之下,在一个"全部或没有"(all-or-nothing)
的风格下。如果存钱失败,那么取钱将会被回滚(roll
back)并且用户的钱将会变得安全。然而,这个改进的
解决方案也有很多缺点:

1.高的网络开销。我们将有6个网络调用,将会降低性能。
(除非我们使用local interface)。

2.差的并发性。如果客户端离服务器很远(如一个applet
或application和远程的EJB系统交互,甚至可能通过
internet或一个防火墙),这个事务将会持续一个很长的
时间。这将导致超额锁定(excess locking),增加冲突
和死锁的可能性,并且降低了其他客户端存取同一个
entity bean实例的并发性。

3.高耦合。我们的客户端直接写一个entity bean的
API,这将使客户端和entity bean紧密的耦合在一起。
如果entity bean层需要在将来变化,我们也必须改变
客户端。

4.差的可复用性。执行“传送存款”的用例的商业逻辑
直接被嵌入到客户端。那么它将被有效的套在了那个
客户端中。其他类型的客户端(Java application,
applet,servlet,等等)不能重用这个商业逻辑。这个
把表示逻辑和商业逻辑混在一起是一个差的为任何
重要的发布的应用设计。

5.差的可维护性。
JTA的使用导致完成事务的中间件逻辑和应用逻辑交织在
一起。通过宣称(declarative)事务分离这两个会更干净,
所以我们能拧(tweak)和调(tune)我们的中间件,而且
不会影响我们的商业规则。

6.差的开发角色的分离。一个通用的在大型项目的实践
把表示层逻辑程序员的开发任务(如serlet和jsp开发者)
和商业逻辑/中间件程序员(EJB开发者)分离开来。如果
商业逻辑和客户端/表示层一起编码,一个清楚的角色
区分是不可能的。商业逻辑和表示逻辑程序员将踩着
各自的脚尖,如果同样在表示层编程。

我们的讨论的结论(takeaway point)是我们需要一个
服务器端的抽象作为entity bean的中介和缓冲。
session bean正是为这个设计的。
因此:

   用一个叫做session facade的session bean层来
封装entity bean层。客户端应该只能存取session
bean,不能存取entity bean。

session facade模式把传统的facade模式的好处
应用到EJB,通过完全对客户端隐藏服务器上的
对象模型,通过用session bean层作为客户端
的单独存取点。图1.2描绘了架构通过这个方法
能被改进。session facade模式还通过在一个
网络调用的增强的用例的执行和提供一个干净
的层来封装完成这个用例的商业和工作流逻辑
带来好处。session facade通常作为无状态
session bean来实现。(虽然这个模式可以用
有状态session bean来实现。)

为了描绘这个paradigm怎样工作和这个paradigm
带来的好处,让我们用我们先前的例子。我们用
来的传输存款的用例的商业逻辑现在将在一个
session bean中替代,这个session bean有一个
叫做TransferFunds(userpk,accountpk,accountpk
,amount)的方法。那个Bank Teller session bean
因此完成大批(bulk)对Users和Bank账户的操作,
如图1.3所示。

因为Bank Teller session bean和User和Account
entity bean共存,它应该被hard-coded来和entity
bean通过local interface通信,因此把需要执行
那个用例的网络开销减小到一个调用(从客户端
到Bank Teller的调用)。同样,所有对entity bean
层的更新应该在Bank Teller所发起的事务中完成,
在它的deployment discriptor中定义,几乎总是,
用TX_REQUIRED的设置。这样有效的用一个事物
包装了整个用例,确保所有对entity bean的更新都在
Bank Teller的transferfunds方法所发起的事务中
完成。

session facade模式是今天使用中的最基础的
EJB模式(这就是为什么它是这本书的第一个
模式)。它不但提供性能好处,也建议了为
EJB 系统分配(systems-partitioning)你的
J2EE应用的标准架构,客户端和服务器被一个
session bean层所分离,这个session bean

[1] [2] 下一页

GOOGLE推介

阅读排行

| 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |

版权所有:Cn-Teacher.Com 2006-2020 未经授权禁止复制或建立镜像
Copyright 2006-2020 © 中国教师站 All Rights Reserved.苏ICP备06018635号