叶海松
【摘要】文章分析了软件整合的需求和面向服务构架的特点,论述了如何使用基于面向服务构架的方法对软件进行模块级别的整合,以达到模块重用和降低开发成本的目标;并通过在Moodle的资源页面中嵌入简单的代码调用另一平台的评分模块服务,提供了面向服务构架的整合实例。
【关键词】软件整合;面向服务构架;学习管理系统;Web服务
【中图分类号】G40-057 【文献标识码】A 【论文编号】1009—8097(2009)08—0102—03
一 整合问题的产生
现代社会对软件的需求不断提高,单个的复杂系统所消耗的人力和物力资源急剧上升。为了对付持续改变的需求,软件变得越来越复杂,而软件使用者和开发者的持续投入,使得软件的成本越来越高。在这样的背景下,软件整合,即用多个小系统的整合来代替一个超级复杂的单一系统的方法逐渐受到人们的重视[1]。
在上海师范大学教育技术系实施的“现代教育技术网络课程平台”项目中就遇到了这种情况。在有限的经费投入下,项目使用开源的学习管理系统Moodle在构建了一个在线学习平台,Moodle能够满足我们大部分的需求,包括课程管理、用户管理、资源管理、在线测试和使用报告等。但在用户需求中有一条在Moodle的核心组件没有提供,即对课程资源的投票评价功能(如图1),项目要求能够让用户对资源进行无记名的评分,然后提交结果,同时会看到总体的评分情况。
这个功能在另一套成熟资源库平台中,已有现成的功能模块。但是这个资源库并不是用PHP来实现的,而是使用ASP.NET实现的。如果按照Moodle的模块设计接口,没有办法直接将已有的ASP.NET的模块嵌入Moodle[2]。因此需要寻找一种能够重复使用既有代码又能在两个系统中保持松耦合关联的方法,让 Moodle能够完全调用原有的ASP.NET的模块,只增加少量的PHP代码来实现整合工作。并且新增加的功能不影响原系统的稳定性,即便新功能失效也不影响系统的运行。在研究各种整合方法后,我们选择了面向服务的整合框架。
二 面向服务的整合思路
1 面向服务的特点
整合的基础是建立系统之间的对话机制,面向服务的构架提供了一种基于消息的对话机制。基于消息的模式通过传递数据块来实现关联,这些数据块与原系统的运行逻辑无关,这样的数据块统称称作“消息”[3],如图2。
图2中网络右侧是服务提供者,它通过接口的形式暴露在网络上,并使用标准的服务描述语言进行描述(如WSDL)。网络左侧的使用者通过接口和描述服务的本地代理来访问服务。在调用过程中,网络上传递的就是消息。消息的格式可以是任意的,由设计和开发者创建。在这里采用的是标准的SOAP协议提供的XML格式的消息。在接口的背后,服务的具体实现和调用的具体技术与接口定义是无关的,只要接口返回的是协商好的消息格式即可[4]。为了最大限度的利用现有的应用程序功能组件,这里将原来的应用组件以WebService的标准方式进行接口封装,并发布在服务器上。
2 整合实例结构
这里所碰到的整合问题是一个典型的异构技术平台的整合问题。Moodle使用的是PHP,而另一个评分模块是运行在ASP.NET上的,PHP不能直接调用ASP.NET平台的组件。使用标准的Web Service则可以解决这个调用问题。图3的结构解释了这个整合的框架。
图3中,我们将原来系统中的Rating模块利用ASP.NET重新进行Web Service的封装,使用标准的接口暴露Rating模块中的投票评价方法。RatingDAL为原系统中负责评分功能的数据层组件。这里仅通过增加服务层组件RatingService对其进行方法的调用,不改变它原有的接口。因为没有对原来的Rating模块作修改,因此不会引起原系统的运行问题。而Moodle中的资源页面作为服务的消费者,可通过标准的SOAP访问RatingService[5]。图3中的RatingService将作为一个独立的服务存在,可以被除Moodle以外的其它程序调用。原来使用RatingDAL组件的模块也可以通过RatingService进行调用。在这个构架中,两个平台所使用的技术不再是主要的矛盾了。
三 技术实现
1 Web服务的封装和发布
在服务实现上,考虑到PHP的交互,我们选择了使用ASP.NET实现基于SOAP标准的Web服务[6][7]。我们通过RatingService,声明了必须的接口,然后通过对RatingDAL的调用完成封装。下面是RatingService的封装代码,可以看到代码中完全是对原RatingDAL的封装,没有任何具体的数据库访问代码。完成后在IIS上发布,测试通过。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class RatingService : System.Web.Services.WebService
{
[WebMethod]
//对原模块的调用,提交用户的评分public int Rating(string applicationid, int resourceid, int score){
RatingDAL dal = RatingDAL.GetInstance();
return dal.AddRatingRecord(applicationid,resourceid,score);}
[WebMethod]
//对原模块的调用,得到具体资源的平均分
private int GetAverageScore(string applicationid, int resourceid)
{
RatingDAL dal = RatingDAL.GetInstance();
return dal.GetStatistic(applicationid,resourceid);
}
[WebMethod]
//对原模块的调用,得到具体资源评分人数
private int GetTotalUsers(string applicationid, int resourceid)
{
RatingDAL dal = RatingDAL.GetInstance();
return dal.GetStatistic(applicationid,resourceid);
}
//其它的WebMethods
//……
}
在这个版本的RatingService中,每个需要进行投票统计的应用程序必须先手动的生成一个GUID作为ApplicationID。以后每次记录投票和统计时都必须提供相应的ApplicationID。
2 Moodle的Web服务调用
在Moodle调用方法上,可选择PHP调用Web服务,或者使用JavaScript进行Ajax调用。考虑到跨域访问的安全性问题,我们选择了使用PHP的PEAR_SOAP模块。
在Moodle中我们找到显示资源的页面,moodlemod esourceview.php文件。我们在该文件中使用HTML设计如图1的界面,然后增加Web服务的调用代码。
首先,利用soapclient对象访问RatingService,获得其接口方法,并创建服务代理,代码如下:
表2 WebService声明
include(“SOAP/Client.php”);
//设置ApplicationID,这个ID是手工注册生成的
$applicationid=”3c4b5694-339c-4fe6-8248-4409f2eb1050$wsdl=new”;
//获取自动生成的WSDL代码
$wsdl=SOAP_WSDL(“http://localhost/Rating/RatingService.asmx?WSDL”);
//根据$wsdl生成RatingService的代理$soapclient
$soapclient=$wsdl->getProxy();
然后,进行投票记录,通过$soapclient调用Rating方法,记录投票的分值:
最后,获取评分情况,存储在变量中,供下文应用:
表4 WebService的数据读取方法调用
//调用RatingService的方法,分别得到平均分和评分用户数
$average=$soapclient->GetAverageScore($applicationid, $id);
$totalusers=$soapclient->GetTotalUsers($applicationid, $id);
……
//在相应位置显示平均得分和参与用户数
最终结果如图4所示。
上面的实例中Moodle本身并不是面向服务构架,但是PHP有支持Web Service调用的模块,为实施整合提供了条件。实例中,我们没有对原评价模块作过多的调整,只是将它通过Web Service进行封装发布,实现了服务和具体调用的分离,不仅为Moodle提供了服务同时也可以向其它应用程序提供评分的服务。上述实例在本地机Moodle1.9/PHP/Apache/MySql/Windows和ASP.NET2.0/IIS5/MSSQL/Windows环境下调试通过。
3 进一步的研究目标
文中的两个系统是在同一个服务器上运行的,因此并没有涉及到有关安全性的问题。在后续的应用中,可能会遇到分布式的调用,因此对WebService安全性的控制将是下一步的研究目标。
四 小结
综上所述,软件整合的目的是充分重用现有的软件,减少软件维护和开发的成本。要达到这个目的,整合的方法是很重要的,不然很有可能会和预期的目标被道而驰。本文研究的面向服务的软件整合方法,在使用不同技术实现的软件中,通过基于消息的通讯来实施整合,大大减少了软件之间的依赖性,提高了整合的可靠性。当然,任何方法都不是万能的,具体的整合过程还牵涉到原有系统的开发框架、目标软件本身的可靠性和可扩展性都等因素,在实施软件整合时要结合各种实际情况进行综合的研究。