构件化软件中非功能特征组装方法 【技术领域】
本发明涉及一种软件系统的组装方法,尤其是一种构件化软件系统的非功能特征组装方法,属于软件技术领域。
背景技术
在Internet成为主要的软件运行平台以及“软件作为服务”的新型产品模式下,软件系统的非功能特征显得尤为重要,如安全、事务、可靠性等。对于通过一组预制构件(Component)组装而成的应用系统而言,这些非功能特征往往涉及系统中的多个构件,同时,实现这些非功能特征的策略与机制大多特定于具体的应用。例如,一个构件在某应用中需要安全保护,某些关键操作还需要保证事务性,而在另一个应用中可能不需要安全保护,也不需要事务保障。因此,在构件制作阶段就全面地考虑这些非功能特征不但难度大,而且也不必要。在构件制作阶段就着手解决某些非功能特征,通常的做法是,将相关代码硬编码到构件实现体中,这样虽然可以使构件实现了非功能特征,但是却增加构件自身的复杂度,影响其性能和稳定性,更严重地是,不论是否需要或好用,目标系统在复用这样的构件时都需要迁就其硬编码的非功能特征,导致该构件的可复用性大大降低。
侧面(Aspect)用于描述系统中跨越多个构成成分的贯穿特性。这些特性既有功能性的,也有非功能性的,现有的侧面技术主要致力于解决全新开发的系统中的非功能需求的问题,并且取得了较好的成效,但是,却没有考虑如何解决基于复用的系统组装中的非功能需求的问题,而且,侧面的复用率、目标系统的复用率较低,形成一定程度的资产浪费。
【发明内容】
本发明要解决的技术问题主要在于,针对现有技术中的构件化软件中非功能特征组装方法存在的构件可复用性低,侧面的复用率、目标系统的复用率较低的问题,提出一种灵活、开放、简单易行的方法,由构件提供主体功能特征,侧面提供非功能特征,保证构件组装而成的目标软件系统满足特定的非功能需求,侧面与构件在设计、实现阶段相互独立,保证构件的可复用性,在系统运行阶段,构件运行支撑平台负责建立并维护构件与侧面之间的关联,保证构件在运行过程中表现出指定的非功能特征。
本发明是通过如下的技术方案实现的:
一种构件化软件中非功能特征组装方法,包括如下步骤:
步骤一、建立包含侧面的软件体系结构,具体包括:实现与构件相互独立、提供非功能特征的侧面;在体系结构建模阶段建立侧面与构件之间关联的描述机制;
步骤二、自动生成包含构件实现与侧面实现的可运行代码以及针对构件、侧面、系统的部署描述符的软件包;
步骤三、在运行阶段根据体系结构规约建立和调整构件实例与侧面实例之间的关联。
步骤一中实现与构件相互独立、提供非功能特征的侧面的具体步骤为:定义侧面激活时机及其与构件之间的交换数据,以及侧面可执行的操作。
所述的激活时机包括:构件实例创建前后、构件实例删除前后、构件实例方法调用前后以及上述操作产生例外之后。
激活的侧面可根据当前上下文执行与非功能特征相应的动作,所述的当前上下文包括:构件实例的状态、标识以及方法调用请求的内容。
所述侧面的实现语言由构件运行支撑平台决定,当构件平台为J2EE应用服务器时,侧面可采用Java或C/C++实现;当构件平台为.NET时,侧面可采用任何CLR(Common Language Runtime,通用语言运行环境)支持的编程语言,如C/C++,C#,Basic等。
步骤一中的描述机制为在体系结构建模时设定语言元素,分别为:侧面元素,用于描述侧面实现提供的操作以及该操作可在哪些激活时刻执行;插入点元素,用于描述某构件允许插入侧面的具体操作;编织元素,其描述了在构件插入点插入的侧面及该侧面执行的操作。
步骤二中的构件、侧面、系统的部署描述符由体系结构建模语言书写的设计文档半自动化生成。
所述的步骤三中在运行阶段构件实例与侧面实例之间的关联的建立过程为:装载并实例化指定的侧面,然后建立与构件实例之间的关联。所述的装载是指构件运行支撑平台解析部署描述符并读取侧面的可执行代码,实例化指的是构件运行支撑平台创建侧面实例并将之与指定的构件实例关联起来。侧面实例与构件实例之间的关联采用截取器(Interceptor)模式实现,即,与某个构件实例关联的所有侧面实例组成一个链路,安置在客户端与构件实例之间,在构件实例调用前后、实例创建与实例删除以及例外产生后被激活并执行相应动作。
所述的步骤三中在运行阶段构件实例与侧面实例之间的关联的调整具体包括增加侧面,用于满足新的非功能需求;当已有的非功能需求不再需要时删除侧面;当已有的非功能需求产生细微的变化时替换侧面,当已有的非功能需求之间的优先级别发生改变时调换侧面实例的先后次序。
由于截取器模式中的截取器具有即插即用的能力,因此,侧面实例及其与构件实例的关联在运行时刻可以进行适度的调整。这种运行时调整的能力适合于非功能需求经常变化、尤其是需要保持7(天)×24(小时)不间断运行的高可靠系统。
采用本发明的方法,同一个构件在不同应用中复用时,只要与不同的侧面关联,就能满足应用的非功能需求,极大提高软件构件的可复用性;在保持当前系统持续运行、构件实例不受影响的前提下,可以在线调整非功能特征,这对于目前基于Web的大型软件系统的开发、集成、演化具有十分重要的意义。另一方面,同一个侧面可在同一个应用或不同应用中与多个构件关联以实现非功能特征,这使侧面也与构件一样成为一种可复用的资产,增加了软件复用在目标系统中的比重。
【附图说明】
图1为本发明所述的组装方法流程图;
图2为本发明一实施例的组装示意图。
【具体实施方式】
以下结合附图和具体实施例对本发明进行详细说明。
一种构件化软件中非功能特征组装方法,如图1,包括如下步骤:
步骤一、建立包含侧面的软件体系结构,具体包括:实现与构件相互独立、提供非功能特征的侧面;在体系结构建模阶段建立侧面与构件之间关联的描述机制;
步骤二、自动生成包含构件实现与侧面实现的可运行代码以及针对构件、侧面、系统的部署描述符的软件包;
步骤三、在运行阶段根据体系结构规约建立和调整构件实例与侧面实例之间的关联。
具体说明如下:
由于侧面可能与任意的构件关联,因此,侧面的实现对构件的依赖必须降至最低。同时,侧面的实现还必须便于运行时刻与构件建立关联,并在需要时在线增加、删除或替换。典型的侧面实现技术作用于编程语言,程序编译之前侧面与主体程序分离,编译后则成为不可分割的整体。对构件组装而言,采用这种实现方式的构件是一种硬编码非功能特征的构件,具有难以复用的缺点。为此,本发明采用侧面与构件在运行时才编织成一个整体的系统构造方式,确保构件的可复用性,兼顾普适性与实用性,本发明定义了侧面激活时机及其与构件之间的交换数据,以及侧面可执行的操作。侧面可在构件实例创建前后、构件实例删除前后、构件实例方法调用前后、以及上述操作产生例外之后被激活,激活的侧面可根据当前上下文执行与非功能特征相应的动作,典型的当前上下文包括构件实例的状态、标识以及调用请求的内容,特别地,这些当前上下文就是侧面与构件之间交换的数据。遵循这组规则的侧面都可以在系统设计阶段和运行阶段建立与指定构件的关联,实现特定的非功能特征。侧面采用的实现语言由构件运行支撑平台决定,如构件平台为J2EE应用服务器,则侧面可采用Java或C/C++实现,而构件平台为.NET时,则可采用任何CLR支持的编程语言,如C/C++,C#,Basic等。
当实现了与构件相互独立、提供非功能特征的侧面之后,要在体系结构建模阶段建立侧面与构件之间的关联。体系结构建模语言必须能够描述符合上述实现方式的侧面及其与构件的关联。为此,本发明定义了三种新的语言元素,其中,侧面元素描述了侧面实现提供的操作以及这些操作可在哪些激活时刻执行,如下列描述所示:
<aspect>
<aspectName>Security</aspectName>
<beforeInvocation><signature>accessControl</signature>
</beforeInvocation>
<beforeInvocation><signatute>authorize</signature>
</beforeInvocation>
……
</aspect>
其中,侧面元素由<aspect>标识,侧面实现提供的操作由<signature>标识,激活时刻的表示如<beforeInvocation>,表示调用前激活侧面。
插入点元素由实例名(ownerName)、扮演者名(playerName)、方法名(methodName)这样的三元组组成,用以确定侧面要影响到的具体某个方法,如下列描述所示:
<joinPoint>
<ownerName>shoppingCart</ownerName>
<playerName>ShoppingCart</playerName>
<methodName>getTaxes()</methodName>
</joinPoint>
其中,插入点元素由<joinPoint>标识,实例名由<ownerName>标识,扮演者名由<playerName>标识,方法名由<methodName>标识。
编织元素用于描述在构件插入点插入的侧面及该侧面执行的操作,
<weaving>
<beforeInvocation>
<refAspect>Security</refAspect>
<refMethod>accessControl</refMethod>
<property>
<Name>role-name</Name><value>administrator</value>
</property>
</beforeInvocation>
</weaving>
其中,编织元素由<weaving>标识;在构件插入点插入的侧面由<refAspect>标识;执行的操作由<refMethod>标识,<property>表示侧面与构件之间交换的数据。
在体系结构建模阶段建立了侧面与构件之间关联的描述后,体系结构建模工具可自动生成包含构件实现与侧面实现的可运行代码以及针对构件、侧面、系统的部署描述符的软件包。然后将软件包部署到应用服务器,该服务器根据部署描述符装载软件包中的可运行代码并实例化,在运行阶段根据体系结构规约建立和调整构件实例与侧面实例之间的关联。
在软件运行阶段,构件运行支撑平台解析部署描述符,读取与侧面元素、插入点元素、编织元素等信息相关的内容,装载并实例化指定的侧面实现,然后建立与构件实例之间的关联。针对前面提出的侧面实现方式,侧面实例与构件实例之间的关联可以采用截取器(Interceptor)模式实现,即,与某个构件实例关联的所有侧面实例组成一个链路,安置在客户端与构件实例之间,在构件实例调用前后(实例创建与删除也可视为特殊的调用)以及例外产生后被激活并执行相应动作。
以下结合图2,以基于ABC(Architecture Based Component Composition,基于软件体系结构的构件组装)方法的实现为例,对本发明的技术方案进行详细的说明。
ABC方法将现有的软件体系结构方法与基于构件的软件开发方法结合在一起,把软件体系结构作为系统蓝图而使用中间件技术作为系统运行的支撑平台,并利用映射规则和工具来缩小设计到实现的距离。将侧面引入ABC方法的具体工作包括:在体系结构描述语言ABC/ADL中增加侧面描述的语言元素,即侧面元素、插入点元素、编织元素,在可视化体系结构建模工具中增加侧面的表示,具体而言,就是将侧面表示为一种特殊的构件,该构件的属性包含侧面元素中的所有内容;侧面与构件之间的关联表示为一种特殊的依赖,该依赖的属性包括插入点元素与编织元素的内容。在特定于J2EE应用的软件包自动生成工具中将侧面描述写入部署描述符,J2EE应用服务器支持截取器模式。引入侧面之后的基于ABC的系统组装过程具体如图2所示,包括:
首先,根据系统功能需求从可复用资产库中选择J2EE构件,并通过连接子建立构件之间的交互关系,完成系统主体功能的设计;
然后,根据非功能需求从可复用资产库中选择侧面,如图中的安全侧面、事务侧面,并在体系结构描述语言ABC/ADL中增加侧面描述的语言元素,即侧面元素、插入点元素、编织元素,建立其与构件之间的关联,从而完成系统非功能部分的设计;
通过上述两步完成了包含侧面的软件体系结构的设计。
接下来,根据上述的软件体系结构自动生成特定于J2EE的应用软件包,应用软件包中包含了一个以上的构件以及一个应用部署描述符文件。其中,每一构件包含构件实现的可运行代码以及一个构件部署描述符文件,构件部署描述符文件包括很多内容,诸如构件信息、依赖引用、资源引用、安全角色、事务属性等;所有构件共用应用部署描述符文件中的应用系统配置信息,包括安全角色、名字服务、事务属性、通信服务等。
最后,通过部署工具将软件包安装到J2EE应用服务器,该服务器将根据部署描述符装载软件包中的可运行代码并实例化,其中,侧面实现被实例化后以截取器的形式插入构件容器,并在指定时刻执行非功能特性,所述的指定时刻为构件实例创建前后、构件实例删除前后、构件实例方法调用前后、以及上述操作产生例外之后。例如,构件实例创建前,同类型构件实例总数已经达到上限,则不允许创建新的实例;构件实例删除前,若实例总数达到下限,则不允许删除该实例;构件实例方法调用前,往往需要激活多个截取器以协助构件调用公共服务从而实现非功能特征,如通信截取器调用通信服务实现构件的分布化访问,日志截取器调用日志服务记录构件的使用情况,认证截取器利用认证服务实现构件的安全访问控制,而事务截取器则调用事务服务以保证构件的事务特性;上述方法调用产生例外时,可能需要执行一些用户定制的例外处理,如事务处理失败需要回滚整个事务。
本实施例在运行时会根据具体的应用环境及应用要求调整侧面,此时调整侧面就是调整相应的截取器,如,为提高性能而禁用日志,只需从截取器链中删除日志截取器即可;需要加密调用请求只需在通信截取器之前增加一个加密截取器;改变访问构件所使用的互操作协议只需替换现有的通信截取器;调整构件的事务策略则改变事务截取器的属性即可。
通过本方法实现的构件化软件,其中的构件与侧面相互独立,构件与侧面可以被不同的应用复用,提高了构件及侧面的复用性;且当该目标软件在运行时,可以根据需要调整非功能特征,使目标软件的应用更加灵活,这对于目前基于Web的大型软件系统的开发、集成、演化具有十分重要的意义。
最后所应说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的精神和范围,其均应涵盖在本发明的权利要求范围当中。