J2EE业务层模式--会话门面
问题:
需要把业务组件和业务服务暴露给远程客户端。
之所以使用会话门面,是出于两个考虑:一是要控制客户端对业务对象的访问,二是要降低远程客户端和细粒度的业务组件、业务服务交互造成的网络负载。
客户端对业务组件的访问 通常,多层的J2EE应用系统有一些服务器端组件,这些组件可能以业务对象、POJO或者实体bean的形式出现。但是如果暴露了这些组件,让客户端直接访问他们,就可能导致一下问题:
--在客户端和业务组件之间存在紧耦合,这也就导致了两个层次之间存在直接的依赖关系,如果修改了业务组件接口,这也会直接影响客户端。
--直接让客户端访问业务组件,也会要求客户端包含复杂的逻辑,因为这样客户端才能协调多个业务组件、与他们交互,并且这也需要客户端能够“感知”这些业务组件之间可能存在的复杂关系。这样一来客户端就要包含一些复杂逻辑,完成寻址、事务划界、安全管理等功能,而且还要执行业务处理。从而加大了客户端的复杂度和责任。
--如果有多种不同的类型的客户端,那么让客户端直接访问业务组件,就会导致对通用业务组件的用法不一致;因为每一种客户端都包含了独立于其他种类客户端的交互逻辑。这可能也会导致不同客户端之间的代码重复,所以降低系统实现的可维护性和灵活性。
远程客户端访问粒度的组件 应用程序可能包含细粒度的业务层组件和服务,而这些组件/服务却要有远程客户端访问。如果客户端直接访问业务组件,那么他们可能会对多个细粒度组件进行多次的远程访问,这会让应用系统变的非常罗嗦,大量的远程网络调用会降低系统的网络性能。
约束:
需要避免客户端直接访问业务层组件,从而防止客户端和业务层之间出现紧耦合。
需要给业务对象和其他业务层组件提供一个远程访问层。
需要聚合应用服务和其他服务,并把它们暴露给远程客户端
需要把所有需啊哟暴露给远程客户端的业务逻辑集中起来、聚合起来
需要隐藏业务组件和业务服务之间复杂的交互和依赖关系,从而提升系统的可维护性,集中处理逻辑,提高灵活性,增强对变化的能力。
解决方案:
使用会话门面,封装业务层组件,对远程客户端暴露粗粒度服务。客户端不用直接访问业务服务组件,而是访问会话门面。
会话门面由session bean实现,负责与业务组件<比如业务对象、应用服务等>的交互。会话门面提供了一个远程的服务层,它暴露给客户端需要使用接口。
当会话门面中包含的业务逻辑比较少、甚至一点儿也不包含的时候,他也最为有效。如果存在业务逻辑的话,就应该放在应用服务里面,而会话门面负责调用应用服务。
设计手记:用例和会话门面
那么如何通过考察用例来确定会话门面呢?如果把每个用例的都映射为一个会话门面,最后就会产生太多的门面。这也违背了“使用少量的粗粒度的session bean”的设计意图,所以我们不推荐这种做法。
应该在给过程建模、设计服务的过程中,一边确定用例一边就确定相关的服务。然后,就要组合和分隔这些服务,以便把他们实现粗粒度的会话门面。或者也可以把这些服务设计为一个“应用服务层”,然后通过一个“会话门面”层把这个“应用服务”层暴露给远程客户端。通过这种做法,把相关的服务组合到一起,就能让应用系统中存在较少的会话门面。