Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » Design Pattern & UML  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 EJB设计模式之EJB Command
Pcman



发贴: 0
积分: 0
于 2002-07-24 14:44 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
EJB Command

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

怎样让一个开发者用一个轻量级的态度实现一个用例的商业逻辑,使客户端和ejb解耦并且用一个事务和一次网络调用执行用例?

设计ejb系统时的一个重要的架构决定是把商业逻辑放到什么地方?一个用例的商业逻辑是代表你的领域模型中的合适的方法或跨多个其它entity bean 和/或session bean执行逻辑(工作流逻辑)。

把商业逻辑放到客户端(servlet,applet,等等)有严重的负面效果,影响性能和可维护性,如session facade模式所解释的。问题可以被使用session facade模式纠正,需要把商业逻辑放到session bean中,sessionbean的每个方法映射到一个特定的工作单元,或者用例。这样做,客户端被从服务器端的对象模型屏蔽起来,并且在一个事务和一次网络调用的round trip中执行用例。

session facade模式自己是ejb开发的关键,不过也有它自己的缺点。直接从客户端调用session facade会导致客户端和服务器之间的依赖(在一个大型项目和复杂的客户端代码中),因为对EJB的紧耦合,如BusinessDelegate模式所讨论的。这些问题能被用 business delegate解决,增加一个封装所有对ejb层的存取的对象层。businessdelegate能帮助让客户端代码简单,使客户端和服务器之间的依赖最小。

然后session facade模式和business delegate模式一起提供了使客户端从服务器端的实现细节解耦并允许在一个网络调用和一个事务中执行用例的格式下写商业逻辑的最好的实践。

和通常一样,有trade-off:
1.更慢的开发过程。因为用例逻辑(经常会变化的)在一个session bean中运行,任何时候一个用例需要改变(就是,增加一个参数到一个方法或返回一个额外的属性),实现那个用例的session bean方法可能需要修改。改变一个session bean的过程不是可以忽略不计的----一个改变通常需要编辑3个不同的文件(接口,bean class,deployment descriptor)并且对ejb server的重发布和可能的重起服务器。附加的,封装变化的session bean的在客户端的business delegate将也需要修改。

2.大型项目中的劳动分工将更困难。依赖于一个项目中跨开发者分配工作的策略,session facade是导致不同组或开发者互相争斗的瓶颈,因为它将是随着项目进展时经常变化的主题。

3.在一个大型公司中服务器资源经常被一个小组控制。对一个有建立了的并且正在工作的发布的ejb集合的大型
公司,很难让其他项目的小组对已有的类施加影响和改变。

简单说,用session facade和business delegate开发会导致长期的变化->发布->测试的round-trip,会成为大型项目的瓶颈。问题的关键是商业逻辑放在一个session bean层,几乎是重量级的开发。

综上所述:
使用Command模式来封装商业逻辑到轻量级的command bean,使客户端从EJB解耦,在一个网络调用中执行,作为EJB层的一个facade。

一个command bean只是一个有get,set和一个execute方法的普通Java类,和最初的command模式(四人帮(gof),1995)描述的一样。应用到EJB,Command模式为了达到和session facade和business delegate相同的好处提供了一个轻量级解决方案:
一个隐藏ejb层的对象模型,在一个事物和一次网络调用中执行一个用例,完成使客户端从ejb解耦的facade。command模式通过提供本地交互的类达到这一点,不过实际上在一个远程ejb服务器上执行,对客户端透明。

Command被用来封装应用程序中的单独的工作单元。比如placeOrder,transferFunds,等等的用例,将有它的商业/工作流逻辑封装在只为那个用例的特定的Command,如图1.7所示。

和一个command交互的客户端十分简单。一旦一个客户端得到一个command(创建一个或从一个factory得到,取决于实现),它只是简单的对command设置属性,直到command包含所有需要执行用例的数据。这时客户端能调用command的execute方法,然后简单的执行command上的get直到得到所有command和用例的结果数据。

当客户端执行command,有趣的事情在幕后发生。不是本地执行,command实际上传输到一个远程ejb服务器并在ejb服务器的JVM中执行。然而,所有的在执行用例的过程中被command调用的ejb发生在ejb服务器上,一个用例能在一个事物中执行。这个行为的实现机制晚些时候将在这个模式的讨论中讲解。

使用transfunds例子,一个客户端将设置用来取钱,存钱,传输量的账号的ID。调用transfunds command的execute后,客户端将得到最后账户的平衡,如1.8图所示。

可能Command模式最完善的实现之一是IBM的Command框架,和websphere一同出现,是IBM为电子商务的模式的一部分。有很多实现ejb command模式的方法,不过他们都有3个要素:

1.Command bean。一个有get,set和一个包含需要执行一个用例的商业逻辑的execute方法的简单的java bean。command bean是应用程序开发者需要写的command模式的唯一部分,下面所解释的其他组件是可以跨工程复用的。

2.客户端路由逻辑。通常负责执行命令(command)并把它发送到远程ejb服务器的一个类的框架。这个路由逻辑通常对客户端不可见,通过调用command的execute方法来触发。路由逻辑/框架是一个普通的能被跨工程复用的类的集合。

3.远程Command server。Command server是简单的接受命令(commands)并执行它们的服务。应用到ejb,command server类是一个接受命令(command)作为参数并本地执行之的stateless session bean。Command server也是
普通的(generic)并且完全跨项目可复用。

客户端和这3个组件之间的交互如图1.9所示。在这个例子中,客户端调用路由逻辑组件上的executeCommand方法。在IBM command框架中,客户端只需要调用command自己的execute,因为方法调用将实际上被command的超类接收到,它是路由逻辑框架的一部分。

在幕后,CommandExecutor代理了对一个ejb command目标(因为它是路由逻辑的一部分,所以没有在图1.9中表示出来)的调用,它被编码成知道ejb并且知道怎样发送命令(command)到command server stateless session
bean。通过接受命令(command),command server简单的调用command的execute方法,command然后继续它的商业逻辑。

Command模式的好处如下:
1.因为轻量级的开发/分发过程,方便了RAD。把一个用例写成Command bean比写成一个session bean方法相对更容易和快速去分发和测试。经常的变化能在一个普通java类上做,而不是一个完全的EJB。

2.把商业逻辑从表示逻辑分离。Command通过封装command内的商业逻辑来作为服务器上对象模型的一个facade,只暴露一个简单的command接口让客户端使用。这个分离让客户端和服务器分开的演进。

3.强制用例在一个单独的round trip中执行。因为command实际上在EJB服务器上执行,只需要一次网络调用(和一个事务)来完成一个复杂的用例。

4.使客户端从ejb解耦。客户端是完全的从服务器的实现细节解耦的--所有它们能看见的只是command bean,
command bean看上去象是本地类。

5.命令(command)可以本地执行或产生哑(dummy)数据。空的或虚的命令(command)能在项目开始前被创建,
允许表示层开发者去对于商业逻辑和ejb小组相对独立的写,编译,和测试他们的代码。

很多方面command模式听起来像个终极的解决方案,综合了session facade和business delegate的好处,和一个
轻量级的基础。然而,好处和通常一样,被重要的trade-off所平衡:
1.非常粗粒度的事务控制。因为command只是普通java bean, 没有自动的标记一个command去在一个特定的事务设置或isolation level下运行的方法,而你用session bean方法可以。Command只能在执行它们的Command server的事务设置下运行。这个的结果是用不同的jndi名字和事务设置(在deployment descriptor中配置)来分发多个command server session bean。路由逻辑组件需要被配置成发送特定的命令(command)到command server。就是说,一种方法想发送只读command到没有事务的session bean,然而更新命令能在command server下用tx_required和可序列化的isolation level运行。

2.command是无状态的。command对象不能存储任何状态到执行它的session bean中。用command模式在ejb层存储状态是不可能的。

3.笨拙的错误处理。因为command框架是通用的(generic),从command只有CommandException能被抛出。这意味着,应用程序异常,如NoMoneyAccountException,需要被捕获并用CommandException封装。然后客户端需要为了特定的异常透视到command对象里面。因为异常不是显式的宣称的,客户端失去了编译期检查异常处理的好处。

4.command在大型项目中会变得无法管理。用成千的command, 大型项目会爆炸的,很多command有重复的商业逻辑的部分,特别当不同的项目小组使用同样的后端领域模型。这使得维护商业逻辑层比起在session bean方法中实现用例的sessionfacade(很好的分组到数目很小的session bean中)困难得多。这种类的激增将是大型项目的严重问题。

5.Command Server ejb-jar紧密的耦合到command bean和其它ejb。因为command bean在command server的环境下执行,为了使command bean反序列化和执行,command bean类需要和command server session bean一起分发(在相同的ejb-jar或EAR中)。这意味着只要command bean变化了,command server session bean EAR或ejb-jar将需要重新分发(因此command server classloader能读到所有包含的command的新版本),为了测试变化,或完全重起(如果你的应用服务器不支持热分发)。还有,command bean需要看见任何在它们的商业逻辑中使用到的home,remote,local home,或local interface。这需要或者当ejb被任何它们的command bean存取时command server分发到相同的EAR,或者存取ejb的interface和command server的ejb-jar打包到一起。

command模式和session facade模式一起提供了两个重要的好处:
他们作为一个facade和它们在一个网络round trip中执行。另一个command模式比session facade模式好的主要优点是把客户端从ejb解耦了,用business delegate和session facade一起也可以达到。因此,开发者怎样从中选择呢?把command看作是更便宜(cheaper)的session bean会有所帮助。它们是轻量级的,更快的先导开发过程,以后来的差的可维护性作为代价。




flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923