会话外观模式与值对象

原创 2003年05月29日 05:31:00

J2EE项目设计与应用中,会话外观是一种普遍使用的模式。它可以使得应用更分布式,代码耦合减少,网络流量减少。总体上他给了客户端粗粒度的访问,保护了服务器端的代码。有人说会话外观模式是一个成功系统必备的设计方案,这是一点也不夸张。在一个成功的分布式应用中不使用会话外观模式简直有点不可想象。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

会话外观不同于前端控制器,他有自己的应用领域,解决不同的问题。在客户端与服务器端联系时,尤其是与EJB交互时,会话外观起重要作用,会话外观可以起到降低客户端与服务器端耦合的作用,当然降低的程度取决于会话外观的实现形式。与值对象配合使用可以降低偶合,与xml配合使用甚至可以解除耦合。

下面我们举一简单的例子来看看会话外观模式是怎样体现这些优点的。考虑一个银行系统中,顾客转帐的例子。设想这样的情景:顾客在ATM对自己的帐户做远程操作,把自己的钱从储蓄帐号转到经常使用帐号。应用中,系统首先要核实客户的身份,然后从储蓄帐户消掉要转的钱,再次在经常使用增加这部分钱。我们用三个EJB来表示这核对帐户(Customer EJB,对存储帐户操作(SavingAccount EJB)和对经常帐户(CheckingAccount EJB)操作,客户端应该遵守的操作流程可以用如下的顺序图表示:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> CSDN_Dev_Image_2003-5-281220010.png

 理解上面的操作流程,需要首先理解EJB的工作原理。本质上EJB是一个框架结构,所以理解工作原理,就是要理解这个框架的运行机理。 EJB中有三个部分,分别供客户端与服务器端使用。比如对客户提供验证的操作的Customer EJB,他有本地接口,远程接口与服务器方方法实现类三个部分。推荐的命名方案是本地接口命名为CustomerHome,远程接口命名为Customer,服务器方方法实现类则命名为CustomerBean.在实现中,因为检验本身是一种抽象行为,要检验的是用户名、密码、开户帐号等系列信息,动作本身是与具体的客户无关的。所以他只需要是一个Stateless EJB,与具体用户无关。这样,他完全可以在容器池中有多个实例对象,实现并行对各种不同用户的核对,提高了访问速度。存储帐户EJB (SavingAccount EJB)和经常帐户EJB(CheckingAccount EJB)的没,命名规则类似,他们也是无状态的会话Bean,理由也类似。

客户端首先获得用户验证、然后可以在储蓄帐目下消去要求转帐额,再次就可以转储到经常帐目了。三个动作我们都用EJB实现。客户端依次与三个EJB交互。我们选取CheckingAccound EJB做研究对象,看看客户端是怎样与这个Bean交互的,从EJB对客户端做的响应,我们可以看到EJB的原理。客户端调用本地方法CheckingAccountHome获得对EJB的引用,Home接口会有一个或多个Creat()方法。这个接口是与CheckingAccountBean互动的,在实现中有个ejbCreateA()方法。这种互动由是通过容器实现的。Creat()方法返回的是一个远程接口,此例中就是CheckingAccount了,客户端就得到了对远程接口的引用了,在远程接口中会有一些方法的引用。客户通过这些方法,对远程操作实现业务逻辑。这些方法的实现必须在CheckingAccountBean中实现。上面的过程我们已经看到,在获得对实现方法调用前客户端不得不与远程交互两次。在核对阶段同样要两次才能取得正确的认证,储蓄帐目的操作也同样如此。明白了操作过程与EJB原理后,我们分析上述客户端调用业务逻辑的方法至少有三点缺陷:

首先,一点没有伸缩性。

其次,这种方法没有一直性的保证。

再次,业务逻辑直接暴露,安全让人担忧。

没有伸缩性是说客户不得不对每个远程的EJB做调用。上面我们看到一个简单的转帐业务逻辑就要求客户端直接与服务器端交互六次。要是有其他的逻辑或者增加一个业务方法,客户端又得重新增加多重调用。如果是不同的客户端有不同的方法,方法调用更是忙上加乱。不良的伸缩性能从这里体现。

在整个转帐过程中,实际上只是一个事务处理过程,要么转成功,要么不成功。所以必须保证saving accountCheckingAccount在一个事务处理中。但是在上述处理中,我们看到这种保证是要求在客户端进行的。为了保证两个帐户的一致性,客户端必须把对两个EJB的调用包装在一个事务处理中。由于网络的不可靠性,延迟和错误在这时很可能会发生,事务处理的时间就自然拉长了,错误的可能性就自然增加,死锁可能造成,一致性也就难以保证。

在注意到客户端对远程方法的调用,发现都是直接调用。显然,这种方法直接暴露给客户端任意调用的方式直接导致服务器端毫无隐私,显然是方法调用的安全处理所不允许的。当然在检查EJB方法调用权限的时候,EJB规范也定义了相应的角色和安全控制,虽然这种把安全问题推到部署阶段的方法是规范允许的。但是这不同于WEB应用,对于商业性非常强的应用更是要寻求更安全的措施来解决问题。

为了克服这些缺陷,我们可以引入防火墙的概念——用Session Façade模式在客户端与业务方法之间加上一层Session bean,这样客户端与远程交互就多了一层“防火墙”,可以获得所有防火墙的好处,顺序图就如下所示了:

 CSDN_Dev_Image_2003-5-281220010.png

在目前网络状况下,网络相对与计算机来说还是一个瓶颈(bottleneck),在使用了Session Façade模式后我们把六次或更多的网络连接减少到了一个。对业务方法的访问变成为本地访问。在计算机与容器的条件下,处理速度自然比网络访问要快。不同的客户都是同一的一次性调用,伸缩性可扩展性由此显现。更重要的是,Session Façade Bean包装了业务逻辑的所有方法,并集中控制事务;业务方法也不在直接暴露在客户端下,一致性和安全性都有了保障——事务处理的严格要求转由服务器端的容器来保证,无疑可靠性大大增强了。在这个银行系统应用中我们使用方法transfer()来在客户端与EJB之间传递数据,当然是通过Session Façade来传了,具体怎么传,在下面对Session Façade模式扩展的例子中会论述到。

总之,我们不用在每次传一个细粒度的方法调用了,可以一次传递所有参数给服务器端,复杂的业务逻辑方法也从暴露给客户端处理成隐藏对客户不可见。复杂性虽然推到了Session Façade Bean中,但是逻辑更独立,耦合性更小了。

在实际的应用中,我们常常使用值对象模式来代替transfer()方法。值对象在客户端与EJB层之间传递、交换数据。一个值对象实际上是一个包装了业务数据的序列化了的类,下面是此银行系统中代替transfer()方法的值对象:AccountTransferValueObject

public class AccountTransferValueObject implements java.io.Serializable {

   private String customerPK;
   private String fromAccountPK;
   private String toAccountPK;
   private float  amount;
   ...
   public String getCustomerPK(){
      return customerPK;
   }

   public String getFromAccountPK(){
      return fromAccountPK;
   }

   public String getToAccountPK(){
      return toAccountPK;
   }

   public float  getTransferAmount(){
      return amount;
   }
  
   public void setCustomerPK(String customerPK){
      this.customerPK = customerPK;
   }
  
   public void setFromAccountPK(String fromAccountPK){
      this.fromAccountPK = fromAccountPK;
   }
  
   public void setToAccountPK(String toAccountPK){
      this.toAccountPK = toAccountPK;
   }
  
   public void  setTransferAmount(float amount){
      this.amount = amount;
   }
}

有了值对象,客户端在需要传递数据时候,就把所有的数据打包在值对象中,然后通过网络发送到EJB层,经过Session Facade Bean交给业务逻辑处理。同样当业务逻辑与客户端交互时,EJB层就会创建一个值对象来包装业务方法需要传递的数据,通过Session Façade Bean传递给客户端。


待续

 

 

J2EE会话外观模式与值对象

在J2EE项目设计与应用中,会话外观是一种普遍使用的模式。它可以使得应用更分布式,代码耦合减少,网络流量减少。总体上他给了客户端粗粒度的访问,保护了服务器端的代码。有人说会话外观模式是一个成功系统必备...
  • zaowei21
  • zaowei21
  • 2007年06月04日 10:50
  • 377

模板方法与外观模式

模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可冲定义改算法的某些特定步骤.Servlet是模板方法的一个典型应用。 /** ...
  • yingjiebohe
  • yingjiebohe
  • 2012年07月12日 11:33
  • 1019

策略模式与外观模式

1.策略 :定义不同的算法族,并且之间可以互相替换;让算法的变化独立于使用算法的客户,以动态的改变对象的行为。 2. 例子:随机生成宠物,并统计各种宠物生成数量。 a) 抽象类:PetCreato...
  • y172158950
  • y172158950
  • 2013年12月17日 11:05
  • 1308

外观模式 VS 中介者模式

看外观模式,自己刚开始的简单理解就是这个模式特别省事,方便自己。 定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 讲述:外观模式是一种使用...
  • huo065000
  • huo065000
  • 2014年04月04日 09:58
  • 1388

装饰模式 VS. 外观模式

一、装饰模式         小菜想要和MM约会需要给自己扮靓,而新入住房子之前也需要对每个房间装修一遍,这些事情都有一个共同的特点,就是一个词“装饰”,我们可以把装饰模式应用在这些事情上面。 ...
  • xdd19910505
  • xdd19910505
  • 2014年04月06日 16:44
  • 1954

外观模式(注意区别于中介者模式)

一.外观模式(有点像中介者模式) 通过一个外观类使得整个系统的接口只有一个统一的高层接口,这样就能降低用户的使用成本,也就对用户屏蔽了很多实现细节,当然在我们的开发过程中,外观模式也是我们封装API的...
  • u011889786
  • u011889786
  • 2016年06月05日 21:24
  • 1660

领域模型-谈实体对象和值对象

http://blog.sina.com.cn/s/blog_493a84550101534t.html 领域模型-谈实体对象和值对象  (2012-05-21 20:01:10) 转载▼ ...
  • wlanye
  • wlanye
  • 2015年12月16日 11:28
  • 1414

值对象与引用对象

概念介绍 对象与对象引用
  • u011453312
  • u011453312
  • 2014年06月03日 22:16
  • 3043

装饰模式、装饰器模式、代理模式、外观模式区别

装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。 用代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象...
  • zhang31jian
  • zhang31jian
  • 2016年01月18日 17:21
  • 2396

装饰器模式、代理模式、适配器模式和外观模式的联系与区别

代理模式VS外观模式VS适配器模式 这三个模式的相同之处是,它们都作用于用户与真实被使用的类或系统之间,作一个中间层,起到了让用户间接地调用真实的类的作用。 简单扣扣字眼 装饰器模式:能动态的新...
  • hp910315
  • hp910315
  • 2016年04月10日 11:24
  • 2742
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:会话外观模式与值对象
举报原因:
原因补充:

(最多只允许输入30个字)