J2EE业务层模式--复合实体
问题:
需要用 entity bean 实现业务领域概念模型。
所谓业务对象,就是包含了业务逻辑和业务状态的对象。在J2EE应用系统中,可以用entity bean 实现业务对象;但是在用entity bean 实现业务对象,会产生一些问题。
第一个问题是,需要决定是使用远程entity bean还是本地entity bean ,远程entity bean 会增加网络负载,所以如果使用不懂就会境地系统的性能。EJB2 技术规范引入了本地entity bean,但对于只支持EJB1.1版本的系统实现来说也就就不可用。有些EJB1.1容器会优化entity bean之间的调用;但是,这种优化时厂商自己的提供的,并不标准。在EJB2.X 的容器中,本地entity bean和它的客户端处于同一虚拟机中,这就能进一步控制系统性能和网络负载。但是还是需要注意,与POJO业务对象相比,entity bean即使处于本地也还不够高效,因为容器还要透明的提供很多优化,另外 ,对于entity bean的每个调用,容器还用提供很多其他的服务,比如安全管理、事务管理等等。
另一个问题是,如何实现entity bean业务对象的持久化存储,当然可以使用“容器-管理持久化”来实现透明的饿持久化,无需自己编写持久化代码。但是,如果有一个以前遗留的持久化实现,或者需要自己的饿持久化机制来实现某些独特的需求,那么CMP可能就不太合适。这样一来,就要实现时BMP,把业务对象保存到数据存储中。
最后,还要考虑一个问题:业务对象的关系使用CMP实现还是使用BMP实现。只有使用了CMP,才能用上CMR,另外CMR还要求所有的entity bean必须是本地entity bean。
约束:
需要避免远程entity bean的缺点(比如网络负载和远程entity bean关系)
需要用定制的或者以前遗留的持久化实现,完成 bean-管理持久化 BMP
在使用entity bean时限业务对象时,需要高效的处理实现对象的父子关系。
需要用entity bean封装并聚合现存的POJO业务对象
需要充分利用EJB容器的事务管理和安全管理
需要把数据库的物理设计对于客户端封装起来
解决方案:
使用符合实体,结合本地的entity bean和POJO,实现业务对象的持久化,复合实体能够把一组相互关联的业务对象聚合为粗粒度的entity bean实现。
在J2EE应用系统中,业务对象被实现为父对象或者从属对象。
父对象可以重用、可以单独的部署,它管理自己的生命周期,并且管理他与其他对象的关系。每个父对象可能会包含一个以上的对象,并管理这些对象的生命周期,这些对象称为从属对象。
从属对象不是子对象啊,从属对象可能包含其他从属对象,也可能不包含。在从属对象的生命周期和它的父对象的生命周期之间存在紧耦合。从属对象并不直接暴露给客户端,客户端只能通过父对象访问他们。从属对象并不独立存在,他们的识别和管理都要依赖于父对象。
使用复合entity bean,就能够实现父对象和相关的丛书对象。业务对象的聚合,能够结合互相关联的持久化对象,形成一个粗粒度的系统实现。这样也就可能减少应用系统中的entity bean的数量。
在EJB1.1的规范中,entity bean只能实现为远程对象。这就意味着要面对各种分布式组件的常见问题,其中主要包括网络负载和对象粒度。在这种情况之下,应该吧父对象实现为一个远程的entity bean,把从属对象实现为POJO。如果把从属对象也实现为entity bean,那可不高明,因为这会降低应用系统的性能,之所以如此,是由于如果entity bean之间存在父子关系,那么这些这些entity bean之间的通信就会增加网络负载。
在EJB2 版本中,即可以巴entity bean实现为远程对象,也可以实现为本地对象。使用EJB2实现entity bean的时候,应该以本地entity bean的形式实现父业务对象。至于从属对象,则可以为POJO(和EJB1一样),也可以为本地的entity bean。而业务对象和从属对象之间的关系,用样既可以使用BMP,也可以使用CMP,如果用CMP实现,那么从属对象就不能使POJO,只能是本地的entity bean。
为了实现业务对象的持久化存储,必须选择是BMP还是CMP,一些新的应用系统会使用于EJB2兼容的容器。CMP越来越受到这系统欢迎。虽然EJB2的CMP比EJB1要复杂的多,但是它也并不能总能符合性能上的需求,而且可能还有一些特殊的需求,或者已经有遗留的持久化方案,这样就没有使用CMP满足需求了,在这些需求下,必须采用BMP来实现持久化。
使用复合实体,能够在应用系统中充分利用entity bean的优势和EJB架构的一些强大功能,比如容器的事务管理、安全和持久化等。
无论使用远程对象还是本地对象实现复合实体,都不应该直接把entity bean暴露个客户端,应该把所有的entity bean封装在会话门面的背后,让客户端访问会话门面,会话门面在于幕后的相关的复合实体交互。
有些时候应用系统的业务逻辑交互很少,业务逻辑很简单,这样可能就会直接把复合实体暴露给客户端,但是这样做的时候应该注意,因为如果应用系统相复杂方向发展,就会遇到诸如系统可维护性之类的问题。
效果:
1、增加了可维护性
如果使用复合实体模式,把业务对象中的父对象实现为entity bean,从属对象则实现为POJO,那么就能够减少细粒度entity bean的数量,如果使用EJB2,可以把从属对象也实现为本地entity bean,以便于EJB的其他性能,比如CMP和CMR,这样就能够提高系统的可维护性。
2、提高了网络性能
把业务对象中的父对象和从属对象聚合聚合成数量较少的粗粒度entity bean,在EJB1的环境下能够提高系统的整体性能。这种做法能降低网络负载,因为他消除了entity bean之间的通讯。对与EJB2,用本地entity bean把业务对象实现为复合实体,也具有这样的优点,因为这样一来所有与entity bean的交互都与客户端同处于本地了。但是记住,即使是本地部署,也不如POJO高效,因为EJB容器还要负责entity bean的生命周期、安全性、事务管理等服务。
3、减少了对数据库方案的依赖
复合实体为数据库中的数据提供了一种对象化的视图。这样数据库方案对客户端是隐藏的,因为entity bean与数据库方案之间的映射被封装在复合实体中,对数据库修改可能会要求修改复合实体entity bean,但是客户端并不会受到影响,因为复合对象没有把数据库方案暴露给外界。
4、增大了对象粒度
使用复合实体,客户端通常就只需要父对象寻址,而不必定位大量细粒度的从属entity bean。父对象对于从属对象起到了门面作用,暴露一个较为简单的接口,隐藏了从属对象的复杂性。复合实体避免了从属对象细粒度方法的嗲用,降低了网络负载。
5、简化了复合传输对象的创建
复合实体能够创建一个包含了改entity bean以及从属对象的所有数据的复合传输对象,而且只需一个方法电泳,就能够把这个传输对象返回给客户端。这减少了客户端和复合实体之间的远程调用词次数。