基于UML模型的多态性与Java接口代码信息一致性检测的方法

2017-02-27 10:58余双双刘慧君杨燕宁
计算机应用与软件 2017年2期
关键词:调用时序代码

余双双 曾 一,2 刘慧君,2 杨燕宁

1(重庆大学计算机学院 重庆 400030)2(软件理论与技术重庆市重点实验室 重庆 400030)

基于UML模型的多态性与Java接口代码信息一致性检测的方法

余双双1曾 一1,2刘慧君1,2杨燕宁1

1(重庆大学计算机学院 重庆 400030)2(软件理论与技术重庆市重点实验室 重庆 400030)

UML模型是面向对象系统开发常用的建模语言,在由模型生成代码的过程中常常出现不一致问题,从而造成系统后期测试成本以及维护成本的增加。而UML模型中的多态性因执行路径的不确定性会对模型与代码的一致性产生重要影响,因此针对此问题提出以UML模型为基准,针对多态特性,对UML模型类图、时序图以及Java接口代码信息进行解析预处理从而获取时序调用图以及代码调用图,并对其进行多态性扩展。根据模型的信息来对代码的信息进行检测,如果出现不一致问题时根据模型信息对代码信息进行修改。通过以上提出的方法能够更加完善模型与代码的一致性检测,使检测更为有效、精准。

UML模型 多态性 多态性扩展 一致性检测

0 引 言

目前国内外针对模型一致性检测与源代码分析工具的研究较多,如Jackson等[1]提到的源代码分析工具的发展,文献[2]中的模型之间一致性检测方法等,但这些研究都没有将模型与代码之间进行检测,文献[3]中虽然针对代码与模型进行了一致性检测,但并未考虑面向对象技术中的多态特性[4-5],而多态性会增加软件可执行路径[6]的数量从而带来很多不确定性,继而增加一致性检测的复杂性,因此考虑模型与代码一致性检测中的多态特性是十分重要和必要的。本文选取UML模型的类图和时序图及Java代码接口信息作为研究对象,针对多态特性的重载和重写两种实现方式,通过类中方法参数列表的匹配以及多态性扩展规则的运用来完成模型的多态特性与相应代码的一致性检测。

1 模型与代码一致性检测流程

多态是表示对于同一个消息,它在被不同的对象接收时可能会产生不同的行为。一致性检测过程中,针对多态性不同的表现形式,需要采取不同的策略。对于重载可以通过直接匹配方法中参数的个数和类型的进行相应的匹配,而重写需要在运行时才能够确定绑定的类型,则采取在动态检测过程中,对调用图实现多态性扩展的方式来完成对重写机制的一致性检测。在这里假设绑定是合理的,即对象引用只绑定到声明类型及其绑定类型。

模型与代码的一致性检测首先需要对UML模型的类图以及Java接口代码信息进行解析获取类方法,并按上述策略对重载的方法进行一致性检测。接着根据解析获取的类间关系对时序调用图以及代码调用图进行多态性扩展,然后将扩展的图按照层序遍历的方式进行遍历并进行节点信息以及边的一致性检测。具体流程如图1所示。

图1 模型和Java接口代码信息一致性检测的流程

2 类方法重载的一致性检测

重载是指一个类中多态性的表现形式,即在一个类中定义多个同名的方法,它们彼此之间参数列表不一致。因此对于重载的一致性检测只需匹配方法的参数列表即可。UML类图很好地描述了类信息,通过对类图以及代码的解析获取类信息,如方法、属性和类间关系等。之后对存在的重载多态特性进行检测,若存在不一致情况,则输出不一致性检测报告。因UML模型是一种半形式化的模型,为了更好地描述和存储模型信息,需要对其进行重新的形式化定义,对类图的形式化定义通常使用类元组CT(Class Tuple)[7]的形式来进行表示,重载的一致性检测具体过程如下:

2.1 类图解析

UML类图包含了一致性检测过程中所需的类信息,对类图解析[8,9]后可以获得方法、属性和类间关系等信息,为一致性检测提供基础。其中对于类名和属性都是提取关键信息后直接进行存储。而对于类间关系,则是先确定是何种类型的关系。如果是关联关系则将其转化成关系属性,如果是继承关系则需标注子类与父类之间的关系,如果是实现关系则标注接口与实现类的关系;然后在关系信息列表中添加对应存在的关系信息。而对于类中的方法信息,则是首先根据上一步确定类间关系,如果存在继承关系,则需要确定每一操作在子类中是否对父类中的方法进行重写。然后提取类方法的可见性、名称、参数列表、返回值类型等基本信息,并将类名一并存储到方法的结构中。UML类图解析的流程如图2所示。

图2 UML类图解析流程

2.2 代码类信息提取

代码解析输入为Java接口代码信息源文件,对其直接进行词法分析和语法分析[10-11],获取一致性检测所需的关键信息,即方法、属性及类间关系。具体算法如下:

输入:Java源代码(包含类的定义信息)

输出:代码静态信息

打开Java接口代码信息文件

currentCode=代码文件的第一行内容

while (currentCode!=null){

if (currentCode包含类定义关键字“class”)

提取className、visibility等属性,存入JavaClass当中;

检测该类是否有直接定义的类间关系,如extends,implements等,存入ClassRelation.

根据类定义后的符号“{”来获取类中属性和方法信息。

if (currentCode包含属性attribute的定义)

提取attrName、visibility、defaultValue、attrType等属性,存入JavaAttribute当中。

if(currentCode包含方法method的定义)

提取methName、visibility、className、returnType等属性,存入JavaMethod当中。

检测方法的参数列表,即符号“()”中包含的参数;

if(参数列表s !=null)

根据符号“,”来分割多个参数

提取各个参数的paraName、paraType、defaultValue,position为参数位置,逐次增加,存入Parameter当中。

currentCode=下一行代码;}

return JavaClass集合;

通过上述算法得到所有源代码中包含的类的静态信息的集合,从而完成对Java源代码解析。其中JavaClass、ClassRelation、JavaAttribute、JavaMethod和Parameter为代码类信息存储结构。然后需要继续执行对classRelation的补充。因为上述算法中只提取了可以直接识别的类间关系,如继承和实现,但是无法全部获取类间的关联关系。所以需要重新检测上述得到的类的属性信息。例如类A中包含类B的关系属性或者关系集合,则说明类A和类B存在关联关系,则在classRelation当中添加一条信息(A,B,Association)。

2.3 重载一致性检测算法

重载特性中的一致性检测就是将模型与代码解析后获取的类信息中的方法进行检测,实质上是检测当方法名一致时,方法的参数列表是否也是一致的。若不一致,则将不一致信息输出。具体算法如下:

(1) 将UML类图解析获取的类中方法以及代码信息提取获取的类方法按照名称排序,逐次比较方法名,若存在方法名称不一致问题则输出方法名不一致信息。

(2) 若方法名一致,则检测相对应方法的参数列表中参数个数是否一致,若不一致则输出参数个数不一致信息。

(3) 若参数个数一致,则检测参数类型的顺序是否一致,若不一致则输出参数类型不一致信息。

上述算法是用于重载的一致性检测算法,是在类一致性的基础上针对类中方法进行的检测,对于方法的重载不仅要方法名一致参数列表也必须一致,若不一致要输出相应的不一致信息报告。

3 类方法重写的一致性检测

重写是父类与子类之间多态性的表现形式,指子类中对父类中的方法进行重新定义,且具有相同的名称和参数列表。因为UML半形式化的特点,将时序图解析后提取的信息无法与Java代码进行直接的一致性匹配,所以需要对UML的时序图以及Java代码进行预处理。采用时序调用图及代码调用图来表示相应的预处理结果,之后对调用图进行多态性扩展,最后完成时序调用图与代码调用图的一致性检测。调用图表示的是树形结构的调用关系,具体定义如下:

3.1 时序调用图定义

时序调用图(Sequence Diagram -Call Graph,SD-CG)

SD-CG=

S为开始结点。

M=是消息的集合,表示调用消息。

cmsgi :=},returnType,className>

className表示该消息接收对象的类的名称。

E:=Mc×Mc表示消息节点间的调用边。

3.2 代码调用图定义

代码调用图(Code Call Graph,CCG)

Gc :=

N:={m1,m2,…,mn}节点的集合,表示程序当中的类包含的方法或者过程这样的单元。

mi=},returnType,className>

E⊆N×N是调用图中的边,反映方法之间的调用关系。

3.3 多态性扩展规则

对于重写来说,需要在运行时才能够确定绑定的类型,即运行时才能确定引用的是父类方法还是子类方法。在消息或方法的调用过程当中,若存在多态性,那么在这种情况下无法确定执行的是基类中的方法还是子类中重写的方法。为了保证一致性检测的充分性,要对调用图进行多态性扩展,同时考虑基类方法和派生类方法。这样才能确保父类引用子类实例以及父类引用自身实例所产生的多态性得到充分的一致性检测。多态性的扩展分为节点的扩展和边的扩展:

(1) 节点的扩展

在前面将时序调用图的消息节点定义为:

cmsgi::=},returnType,className>,则在考虑多态性存在时,该消息所对应的类元组可能不是同一个类元组。那么需要通过className属性去查找相应的类元组CT(c)。在类元组定义时,有对重写(override)的方法进行相应的标记。如果有重写则找到与之对应的类元组CT(c1)或者CT(c2),其中CT(c1)是表示基类元组并且CT(c2)表示派生元组。例如在时序图中存在消息m,它所属的类元组CT(c)存在父类CT(c1)以及派生类CT(c2),那么在将其转换成时序调用图时,对应的消息节点m将扩展为m1和m2。

(2) 边的扩展

对于多态节点m,如果本来存在其上一个节点ma和下一个节点mb,那么在扩展多态节点m的同时,对ma指向m的边ea以及m指向mb的边eb也要进行相应的扩展。例:如图3所示,设消息节点m存在多态性,且扩展节点为m1和m2,扩展的边集合E={ea1,ea2,eb1,eb2}。

图3 多态扩展

3.4 时序调用图的构建及多态性扩展

(1) 同类图解析方法类似,解析获得时序图的动态交互信息,如类对象集合、消息集合、事件集合以及消息顺序集合等。

(2) 构造时序调用图中的开始节点S:S=

(3) 将时序图中的消息msgi逐个转为消息调用节点cmsgi,并以此添加到时序调用图SD-CG中。在转换过程中,对于每个消息都需要考虑到它的发送对象和接受对象,对于时序调用图中的调用消息节点中需要添加关联的对象信息。

(4) 根据时序图中的消息顺序信息建立时序调用图中节点之间调用边的关系。其中如果某一消息m1发送对象为o1,接受对象为o2,而下个消息m2的发送对象通用为o1,对对应节点建立并行的调用边。如果m2的发送对象为o2,则对对应节点建立串行的调用边。

(5) 对时序调用图进行二次遍历,查找出消息节点中存在的多态性问题,并根据多态性扩展规则对其进行多态性扩展。示例如图4所示。

图4 时序图到时序调用图的转换以及多态扩展

根据上述转换规则,成功完成将时序图到时序调用图的转换过程,以及相应的多态性扩展。对象obj3对于消息m2存在多态性,即对于消息m2有不同的实现方式。则在构建时序调用图时,扩展节点M2′。M2与M2′为并行的关系,在后面的一致性检测中将分别对两个节点进行检测。

3.5 代码调用图的构建及多态性扩展

(1) 代码调用图构建算法

输入:Java源代码(包含方法调用动态信息)

输出:代码动态信息(即CCG)

创建CCG的首节点startNode。

定义当前执行节点cNode=startNode;

currentCode=代码文件的第一行内容

while (currentCode!=null){

If(currentCode中存在对方法JavaMethod的定义 ){

创建JavaCallNode--node1,其中nodeName、visibility、returnType、paraterList对应该方法相应属性,className为方法所属类。

首节点s的nextNode=node1,cNode=node1。

If(检测该方法中调用其他方法){

再创建新JavaCallNode--node2。

node1.nextNode=node2,cNode=node2.}}

currentCode=Java代码的下一行内容;}

return callGrap;

根据上述算法完成了对代码动态信息的解析和调用图的构建,这是一个递归的过程,通过递归检测类中相互的调用关系来创建一个树形的Java调用图CodeCallGraph。例如方法A中调用了方法B,则在CCG存在A和B两个节点,并有A指向B的边存在。图5给出了一个代码与代码调用图间的映射关系示例。

图5 代码与代码调用图间的映射关系示例

(2) 代码调用图多态性扩展

① 创建一个待扩展节点列表,并将代码调用图CCG中的首节点加入列表当中。

② 检测待扩展节点列表是否为空,如果不为空则取出列表中第一个节点,然后将该节点所有子节点加入到列表当中。如果为空则结束多态性扩展。

③ 根据②中取出节点的属性className查找该节点所属类,然后根据代码静态信息中类间关系,检测该类中此方法是否存在多态性,如果存在则进入④,否则回到②。

④ 假设某节点mNode存在多态性,则根据其不同的实现方式扩展对应节点:mNode1,mNode2....mNoden。同时扩展相对应的边,分别由mNode的父节点指向扩展节点,以及扩展节点指向mNode的子节点。然后回到②。

上述策略是按照层序遍历的方式对代码调用图这样一个树形的结构进行遍历,并在遍历过程中,对于每一个访问的节点检测其多态性对存在多态性的节点进行扩展。

3.6 重写一致性检测算法

对时序调用图及代码调用图进行多态性扩展后,需要对其进行动态信息的一致性检测,主要分为调用关系集合一致性匹配及消息节点一致性匹配两部分。

(1) 调用关系的一致性检测

对于调用关系集合的匹配,因为本文对SD-CG和CCG的定义都是以一个树形的结构来进行存储,所以调用关系即为树所对应的边。下面给出具体的实现策略:

分别对输入的SD-CG和CCG进行层序遍历,得到边的有序集合Ea和Eb。定义消息集合Message来存储检测到的不一致信息。

① 检测Ea和Eb是否为空,若都不为空,则取出各自第一条边ea和eb,进入③;若一个为空另一个不为空,则视为不为空的边集合剩下的所有边都为缺失的边,将缺失信息存入Message当中;若二者都为空,则检测结束。

② 对比取出的边ea和eb的信息,若不一致则进入④,否则返回②。

③ 若ea和eb不一致,则首先对比其父亲节点,如果父节点不一致,则查找上一条边的父节点,父节点不一致的认为存在边的缺失。

④ 根据③中规则确定所缺失的边,则在Message中存储对应的缺失信息,并将缺失边的集合中剩余的边的序列数全部加一,返回②。

根据上述的策略,完成调用边集合的一致性匹配,并得到不一致信息集合Message。然后根据Message中的信息对节点信息进行标注,从而减少节点匹配过程的匹配数量及因此容易导致的一些错误。图6给出了一个调用边匹配的简单示例:

图6 调用边一致性检测示例

如图6所示,在检测边1、2、3的时候并没有出现问题。但是当检测边4时,左图为B→E,右图为C→F,因为二者上一条边均为B→D,则认为右图对比左图,右图对比左图缺失了边B→E。则将此缺失信息加入Message当中,并将右图中余下的边加一,即C→F编号加一得5。此外在进行节点匹配时,根据边缺失信息,对缺失边上的节点只进行表示,而不用解析检测。即对节点E,仅视为右图中缺失了该节点,而不用将该节点与左图中的任何节点来进行匹配。

(2) 消息结点与方法结点的一致性检测

因为之前已经完成了调用边的一致性检测,并根据边的不一致信息对节点信息进行标注,所以待检测SD-CG和CCG中的节点是按序且相互对应,只需依次提取进行匹配即可。具体算法如下:

输入:SD-CG中节点集合NU和CCG中节点集合NJ

输出:动态信息不一致问题

c1=NU中第一个元素,c2=NJ中第一个元素

while ( c1 != null && c2 !=null ){

if (c1的className属性值与c2的不一致)

message+=“节点”+c1+”与节点”+c2+”对应的类不一致”;

if (c1的visibility属性值与c2的不一致)

message+=“节点”+c1+”与节点”+c2+”可见性不一致”;

if (c1的returnType属性值与c2的不一致)

message+=“节点”+c1+”与节点”+c2+”返回值类型不一致”;

if (c1的paraList属性值与c2的不一致)

message+=“节点”+c1+”与节点”+c2+”参数列表不一致”;

c1=NU中下一个元素;

c2=NJ中下一个元素;}

return message;

4 实验验证

汽车租赁系统类图中一共包含了以下几个类:Person、customer、employee、commonworker、manager、skillworker、car、customerrecord、requestorder等类。其中,employee和customer类是继承于person类,commonworker,manager,skillworker又继承于employee类。图7-图9给出整个汽车租赁系统的类图和取车时序图以及一致性检测报告。

图7 汽车租赁系统类图详细信息

图8 客户取车时序图

图9 汽车租赁系统一致性检测报告

5 结 语

本文是在UML模型与Java代码之间的一致性检测方法一文的研究基础上,结合UML模型和Java接口代码信息的特点,并针对面向对象多态性的机制进行多态性扩展,然后完成了二者之间的一致性检测方法的设计与实现。虽然本文结合多态性的机制对一致性检测的方法进行有效的改进和完善,但是在此仍然存在一些问题和需要进一步完善的地方,如本文在对接口代码信息进行解析时,只是针对于代码中的概要内容,即仅仅针对于接口来实现,而没有对方法内部的实现细节进行考虑。在进行动态性检测的过程中,是通过创建调用图的方法,即一个静态过程来模拟动态行为的形式进行检测。后续工作可以对代码进行更加详尽的解析以及采用真正的动态形式来对代码中方法的调用关系进行检测。

[1] Jackson D,Rinard M.Software analysis:a roadmap[C]//Proceedings of the Conference on The Future of Software Engineering,2000:133-145.

[2] 朱晨.UML模型一致性检测的研究与设计[D].上海:上海交通大学,2007.

[3] 曾一,李函逾,刘慧君,等.UML模型和Java代码之间的一致性检测方法[J].计算机科学,2015,42(4):151-155.

[4] 周建儒,余美璘.面向对象特征之多态性的分析[J].科技信息,2009(35):52,77.

[5] 蓝雯飞,周俊,陈淑清.Java语言的多态性及其应用研究[J].计算机系统应用,2005,14(4):80-83.

[6] 覃钊璇.面向对象多态路径及测试数据生成方法的研究[D].重庆:重庆大学,2010.

[7] Dong W,Wang J,Qi X,et al.Model checking UML statecharts[C]//Proceedings of the 8th Asia-Pacific Software Engineering Conference.IEEE,2001:363-370.

[8]ObjectManagementGroup.UML2.0SuperstructureSpecification[Z].2005.

[9] 丁娜.带OCL约束的活动图多态测试方法的研究[D].重庆:重庆大学,2012.

[10]BergmairR.Syntaxdrivenanalysisofcontext-freelanguageswithrespecttofuzzyrelationalsemantics:UCAM-CL-TR-663[R/OL].http://www.cl.cam.ac.uk/TechReports/UCAMCLTR663.pdf.

[11]BarveA,JoshiBK.Aparallellexicalanalyzerformulti-coremachines[C]//Proceedingsofthe2012CSI6thInternationalConferneceonSoftwareEngineering,2012:1-3.

THE CONSISTENCY DETECTION METHOD OF POLYMORPHISM AND JAVA INTERFACE CODE INFORMATION BASED ON UML MODEL

Yu Shuangshuang1Zeng Yi1,2Liu Huijun1,2Yang Yanning1

1(CollegeofComputerScience,ChongqingUniversity,Chongqing400030,China)2(KeyLaboratoryofSoftwareTheoryandTechnologyinChongqing,Chongqing400030,China)

UML is a common modeling language for object-oriented system development. When the code is generated from the model, the inconsistent problem always exist and it will increase the later test cost and the maintenance cost. Since uncertainty of execution paths of polymorphism in UML model which makes important impact on consistency detection of the model and the code, using the UML model as the benchmark and the polymorphism (Overloading and Overriding) as the key elements, the Sequence Diagram-Call Graph(SD-CG) and Code Call Graph(CCG) is able to be obtained by analyzing and preprocessing the class diagram, sequence diagram and the Java interface code information, which should be treated with polymorphic extension. The code information is detected according to the information of the model, if there are inconsistent problems, the code information will be modified according to the model information. The proposed method can improve the consistency detection of the model and the code, getting more effective and accurate detection.

UML model Polymorphism Polymorphic extension Consistency detection

2015-12-21。国家自然科学基金项目(61272194)。余双双,硕士生,主研领域:软件测试。曾一,教授。刘慧君,副教授。杨燕宁,硕士生。

TP3

A

10.3969/j.issn.1000-386x.2017.02.002

猜你喜欢
调用时序代码
顾及多种弛豫模型的GNSS坐标时序分析软件GTSA
清明
基于不同建设时序的地铁互联互通方案分析
核电项目物项调用管理的应用研究
系统虚拟化环境下客户机系统调用信息捕获与分析①
创世代码
创世代码
创世代码
创世代码
基于FPGA 的时序信号光纤传输系统