2.1.2 服务接口
服务接口的定义在目前的WID中实际上支持两种定义方式,WSDL和Java接口,但一般情况下,模块之间的接口我们使用WSDL,因为WSDL扩展性和通用性都比较好。而模块内部,我们可能使用WSDL,也可能使用Java。如果你的一个Java服务组件不得不引用一个无状态的SessionBean,你就不得不使用该SessioBean的接口来定义这个组件的接口。在使用WSDL接口定义的时候,尽量不要过早的在Process中绑定接口,因为一旦接口的参数的数据组织格式发生变化,Process的调用接口和分配变量部分会发生很大的变化。
如果你希望暴露的接口和你的组件接口不尽相同,你可以使用接口映射,接口之间的映射就需要用到业务对象的映射,而且也可以使用Mediation来做,实际上完成的功能基本上是一样的。
在WID中定义的一个接口示例如图3所示。
图3:WID定义的服务接口示例。
2.1.3 业务对象的映射
SOA采用分层的方法来隔离关注,利用分层可以提高开发和运行时的灵活性,但是层次之间以及层次的对象之间,经常会需要互相映射,这是SOA项目实践中非常常见的一个问题,在定义业务对象的时候,同样需要考虑这样的问题。
SDO的目的是统一数据的格式,然而在遗留系统中难免会有不同的数据源(数据库, LDAP等)虽然SDO提供了访问不同数据源的方式,但是你仍然不能避免SDO和Java对象之间的转化。通常情况下,如果被集成的后台系统是EJB,我们可以使用Web Service来包装EJB,然后在SCA模块中导入该Web Service 可以实现自动调用,在导入WSDL的同时,WSDL中定义的消息会自动转化为BO的XML Schema定义。此时我们就可以通过使用Mapping或者XSLT Transformer来实现BO之间的映射,从而隐式的实现BO到Java的映射。如果你的Java对象的定义不含弱类型对象,或者不含特定的业务逻辑,只是简单的映射,你可以使用JAXB或者XMLBeans轻松的通过配置实现Java对象到XML的映射,通过XML快速生成SDO。
有2种情况你将不得不亲自面对Java对象和BO之间的互相映射(转化):
1 在特定情况下,因为效率,事务等的需要,不得不在SCA中直接集成EJB,并且你无法使用WSDL轻易的实现映射,尤其是当数据种隐含若类型对象或者隐含特定的业务逻辑。对于常见的J2EE系统,我们会遇见诸如Vector,List,HashMap这样的参数类型,对于这些弱类型的Java对象,虽然WSDL提供了Any 类型,但是一般不太容易交互,所以对于这种情况,你不得不需要使用良定义的Java对象来包装参数,或者将包装后的方法暴露成Web Service,或者直接手工实现Java和SDO的转化。
2 对于UI的重用性,有时候也要涉及BO和Java对象之间的转化。
对于这些情况,我们推荐你使用自己编写的TransformerFactory来生成每个对象和SDO的转化类。我们实现的TransformerFactory实际上是一个Java代码生成器。
值得注意的是,在生成Transformer的同时,我们可以捎带生成测试数据生成器,使用该生成器,你可以在项目的早期生成满足需要的测试数据,以方便单元测试,集成测试,实现自动化的测试。
在我们的例子中,银行内部的房贷系统就是这样一个后台系统,它暴露出EJB的接口,并且设计上采用Command模式,其中包含大量的弱类型参数以保证扩展性,因此我们无法使用WSDL映射来实现自动调用,不得不采用Java代码手工转化。我们在生成转化类的同时也生成测试数据生成类,这也是我们使用TransformerFactory捎带带来的一个优点。
3. 按不同类型的服务划分服务模块
根据本系列前面的分析,我们已经定义了将实现的服务和接口,但是如何下手开始做服务的编码呢?在SOA的角度,应用程序无非是服务的装配形式,但是,如何组织这些服务呢?SCA 的组件天然的有2种组装模式,一种是模块组装,一种是系统组装,所谓模块组装,就是SCA定义了一种SCA的模块,模块内部会有一个或多个SCA的服务组件通过流程,调用,等方式组成一组功能的集合,该功能的集合(模块)具有显著的业务层面上的价值和意义,所谓系统组装主要就是BPEL,SCA调用等方式,将不同的模块组织,以完成业务流程和业务功能。
WID 为我们提供了很好的SCA开发环境,在WID的环境中进行SOA的开发一般涉及到 SCA模块,Mediation模块,Library等模块。而一个SCA或Mediation模块就会对应多个WID的Project(一个基本的项目,一个Ear项目,一个EJB项目,还有EJB客户端和Web项目等),如果每个服务对应一个模块,就会产生太多的部署单元,系统给人的感觉整体上会杂乱无章,因此我们推荐使用以下地方做法来给服务归类,使用不同的模块来组织这些服务。
1首先将所有的服务归为大类,对于每一类中的多个服务,按照流程相关,中介相关,现有系统相关,新建服务相关,其他相关等模式进行组织。
2 在这个基础上在按功能和业务逻辑上的相关性进行组合,还要考虑部署,开发等的问题,最终均衡各方面的决策,实现一个比较中肯的分类,要以有利于开发和部署为原则,还要和集成的步骤和层次相吻合。
对于每个服务 ,我们可能会使用一些简单的表格来分析,参见表6。
表6:服务分类分析表示例。
