我的前一篇文章(WLDJ,第3卷,第2期)介绍了一个"处方",它通过使用逐步、循序渐进方法,采用BEA WebLogic Platform来现代化遗留系统。那篇文章以多种方式介绍了"现代化过程",在本篇文章中,我将深入研究跨平台集成和结构设计的细节。
我的前一篇文章(WLDJ,第3卷,第2期)介绍了一个"处方",它通过使用逐步、循序渐进方法,采用BEA WebLogic Platform来现代化遗留系统。那篇文章以多种方式介绍了"现代化过程",在本篇文章中,我将研究跨平台集成和结构设计的细节。我也将使用相同的基于处方的方法来展示如何针对WebLogic构建可扩展、健壮和可维护的现代化平台。在这个过程中,我将介绍一些基本的J2EE模式,在您的设计中,将能够重用这些模式。
我在前一篇文章中提及,集成是整个过程的关键步骤。它的目标是在遗留系统和现代化的WebLogic Platform之间架起一座桥。在许多方面,可以把遗留系统看成想与WebLogic Platform一起集成的某种资源。现代化过程的一个目标是:尽可能让平台避开遗留系统。这样,现代化系统的设计就与它相对独立地发展。让我们来看一下用于集成两个平台和实现集成层的体系结构的最佳实践。
设计分层体系结构
最佳实践是使用逻辑层构建J2EE应用程序。特别是较高级别的层利用了较低级别的层的服务。分层体系结构的思想是:根据通用性组织现代化平台。在分层体系结构中,最特定于应用程序的最顶层包含着一些应用程序系统,可以把它们当成最终用户可用的完整的一套用例。应用程序系统直接下层,特定于业务的层,包含一些特定于业务的组件。例如,对于金融机构,这一层可能包含下面一些可重用组件,它们是账户、客户、财务报表和报告等组件。然后应用程序层可能包含Portfolio管理包,它利用底层可重用财务组件。最后特定于业务的组件下面的一层包括一些基础结构组件,比如日志记录框架和实用程序类。分层体系结构的一些特征是:
· 最顶层是最特定于应用程序的,最底层是最通用的。
· 每层通过一组接口和外观(facade)向它的直接上层公开服务。反过来则不正确,顶层没有向底层公开服务。但位于横向同层的组件可以彼此利用各自的服务和公共接口。
· 分层解决了模块依赖性,因此最小化了编译(build)和打包的时间。
· 不同层之间,数据是通过使用传输对象传递的(参见"实现传输对象")。
这里的层(layer)不要与另一个层(tier)混淆。逻辑层(layer)可能跨越一个或几个tier。(译者注:如果本文没有特别指明,层即为layer的层)。分层实际上是一种逻辑方式,用于组织体系结构并通过外观公开服务接口。图1给出了一个分层体系结构的例子,把银行系统的场景作为一组包依赖性进行例示。
实现传输对象
在设计现代化平台中,起初几个步骤中的一个步骤是确定传输对象。在前一篇文章中可以看到,遗留系统最有可能使用过程语言(比如COBOL)实现。因此,最初的几个任务中的一个任务将是封装遗留系统,这样,就能向BEA WebLogic Platform提供它的一个Java对象视图。然后数据访问对象(参见下一节)将封装遗留服务,并且使用传输对象在遗留系统和WebLogic Platform的不同层(tier)之间传输多个数据元素。那么准确讲,传输对象是什么?传输对象实际上是Java类的一个实例,它用作数据元素的容器,这样,就能在不同层(tier)之间优化数据传输。因此它必须是可序列化的,而且是通过值传递给客户(机)。传输对象通常只对它的成员提供getter和setter方法。例如,在银行应用程序中,可能想拥有某些传输对象,比如AccountTO、CustomerTO和CreditCardTO,这些对象中包含了有关账户、客户、信用卡的相关信息。这里要强调的一个关键点是:在Java中,传输对象可有效地用于构建遗留系统的域模型。因此,花些时间确定遗留系统的业务实体是相当有用的。一个好的定律是:可以把遗留系统中的确认实体映射到对应传输对象。也值得提及的是,传输对象在应用程序资源层(tier)和表示层(tier)之间的每一层(tier)中使用。因此以下面这种方式设计和实现传输对象非常重要:传输对象是可重用的,并且尽可能对应于业务域。最后,在第一版书Core J2EE Patterns中,传输对象称为值对象。但是值对象会使人产生误解。在J2EE模式组把它定义成"一个小的简单对象,像金额或日期范围,它的等式不是基于身份的"前,它使用得很好。另外,传输对象也可等价称为数据传输对象,但为简洁起见,我保持使用J2EE模式组的术语。
实现数据访问对象
数据访问对象(DAO)用于完全封装遗留系统,并向它提供简单一致的接口。DAO允许下面的基本操作:创建、读取、更新和删除(CRUD)和查找。传递给DAO的参数和从DAO返回的参数是传输对象。在例子中,遗留系统将扮演数据源的角色,并且使用DAO检索或更新数据。通常我们在每个传输对象上构建一个DAO。让我们来回顾DAO实现的接口:
· create(aTransferObject: TransferObject): PrimaryKey。create/insert方法在遗留系统中有效地创建新的业务实体,并返回它的主键。例如,在银行系统中,create方法可用于根据AccountTO中包含的信息打开新的账户,并返回账户的主键,该主键也应该是可序列化的对象。
· read(aPrimaryKey: PrimaryKey): 返回对应于主键的传输对象。
· update(aTransferObject: TransferObject): 用包含在其中的新数据更新对应于这个传输对象的主键的遗留业务实体。
· delete(aPrimaryKey: PrimaryKey): 在遗留系统中删除对应于这个主键的业务实体。
· find(aQuery: QueryOperator): TransferObject[]: 把对应于查询操作符的所有业务实体作为一系列传输对象返回。
既然已经指定了DAO的接口,那么如何实现它呢?可以看到,DAO接口的每种方法通常将对应于在遗留系统上运行的一个或多个COBOL服务程序。可以把COBOL服务程序(Service Program,SP)看成一种特殊的COBOL模块,这种模块可以从Java中访问。例如,考虑一下 银行系统。图2在类图中例示了CreditCardTO传输对象和它的CreditCardDAO DAO之间的关系。
清单1展示了CreditCardDAO DAO的可能实现,它使用了AS/400的Java工具箱。注意,我只展示reate方法。
注意,DAO模式具有某种优点,可以让宿主在BEA WebLogic上的组件完全避开遗留系统。换句话说,可以在现代化过程中修改业务逻辑,甚至完全用实体bean替代它,而不会破坏任何依赖于DAO的组件。我们可以使用返回适当DAO实现的Factory方法。
最后,图3展示了客户机(比如会话bean)和CreditCardDAO之间的交互。
关于分布式事务的说明
WebLogic和遗留系统之间的分布式事务的细节超出了本文的范围。主要的难点之一是:事务提交后,如何实现回滚。在例子中,遗留系统上可用的操作是作为COBOL SP公开的,而且一旦调用了SP,就不能再执行回滚。而且遗留系统可能完全不提供任何事务服务,可能只可以把它当成简单数据源。但可以取得与回滚相同的结果,不过要执行"补偿"数据更新。这在遗留系统上模拟了回滚的效果,办法是:在操作后,执行对应的相反操作。这样,就可以把系统还原到初始操作前的相同状态。再次考虑传统银行系统:
· 开始事务:WebLogic业务层(tier)中的T。
· 更新操作:从客户账户中提取金额A。这实际上对应于在遗留系统上使用即时提交的COBOL SP调用。
· 提交:在WebLogic业务层(tier)执行提交操作。这个操作已经在遗留系统上执行。
· 回滚:对于遗留系统,通过使用金额A编辑客户来模拟回滚。
注意,Web服务事务规范正是对长时间事务或业务活动采用相同方法。最后,如果考虑操作的最通用形式,其中混合了JTA资源和非事务性遗留系统,那么可以实现补偿事务,如下面代码段所示:
updateLegacyBankingSystem();
try {
UserTransaction.begin();
updateJTASupportedResource1();
updateJTASupportedResource2();
updateJTASupportedResource3();
UserTransaction.commit();
}
catch (RollbackException ex) {
undoUpdateLegacyBankingSystem();
}
实现用例
第一章文章中介绍的现代化处方提及具有增值的用例应该被确认,并把它当成现代化工作的最初选择,然后重新宿主在WebLogic上。另一个重要任务是确定用例属于体系结构的哪一层。例如,如果确认用例可以由几个不同应用程序或其他用例重用,那么它应该在特定于业务的层实现,并通过外观接口公开。但是,如果用例非常特定于应用程序,那么就应该在体系结构最顶的应用程序层实现。
结束语
在本文中,我提及了一些基本的模式,它们用于设计现代化的BEA WebLogic Platform的体系结构。为同时集成遗留系统和已现代化的系统,我使用传输对象和DAO模式。传输对象已经被用作构建遗留系统的域模型的基础,另外,它还是遗留系统和现代WebLogic平台之间传输数据的基础。也可以使用数据访问对象模式,把遗留系统完全封装成数据源。通常,我们对于每传输对象构建一个DAO。
分层体系结构最小化了现代化WebLogic平台的组件之间的依赖性,并大大改进了重用性。现代化的一个重要方面是,确定遗留系统的价值增值用例,并在现代化平台的某一层中重新实现它们。如果用例是特定于业务的,并可以由其他用例实现利用,那么它应该位于体系结构的特定于业务的层,并且它的接口是作为服务外观公开的。但是如果用例是特定于应用程序的,那么它应该位于体系结构最顶的特定于应用程序的层。既然已经构建了现代化平台的集成基础结构,那在下一篇文章中我将展示,如何使用BEA WebLogic Workshop在体系结构中,构建特定于应用程序和特定于业务的某些层。我将把各部分拼装起来,现代化一个使用WebLogic平台的小型银行系统。我们将看到WebLogic Workshop如何采用有助于设计应用程序的RAD方法。
|