基于规则的结构型设计模式检测技术研究
2015-05-15杨潇
杨潇
摘要:设计模式是面向对象的软件开发中一种可重用的、能够解决软件设计开发中普遍存在问题的方法。识别软件系统中的设计模式能够帮助相关开发人员和维护人员更好的理解软件系统的设计。尤其是GoF[1]中的结构型设计模式,解决了如何组合类和对象获得更大结构的设计问题。所以对于结构型设计模式的识别能够有效地提高软件的理解和可维护性。在该论文中展示了是一种识别面向对象软件系统中设计模式的方法。该方法能够自动的识别出软件系统中的结构型设计模式。
关键词:设计模式检测;源代码分析;逆向工程
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)08-0236-04
Abstract: Design Patterns are reusable design elements in object-oriented software design and development. Design Patterns aim at providing solutions for recurring design problems in software development. Detecting design patterns in existing software systems can improve the comprehension of software systems. The structural design patterns mentioned in GoF Patterns[1] are concerned with how classes and objects are composed to form larger structures. Thus, detecting structural design patterns are extremely useful for software comprehension and maintenance. In this paper I present an approach to detect design patterns in object-oriented software systems. It is an approach for automatically detection of structural design patterns.
Key words: design pattern detection; source code analysis; reverse engineering
1 課题背景
对软件系统的全面深入理解对于现代软件工程的发展有着举足轻重的作用。因为软件理解是保证软件有效维护和再工程的一个重要因素[2]。随着软件规模的日益增大,软件理解的工作变得越发的重要。
如果软件系统具有完整的文档信息,那么想要全面理解一个已有系统也并非难事。但是,现实的状况是在软件开发的过程中相关文档缺失、不全面,或者文档与系统不一致。这样则给软件理解造成了很大的阻碍。由此也导致了软件维护和再工程的代价昂贵、需要耗费大量的人力物力或者根本无法得以继续。
由于设计模式中包含了解决一般常见设计问题的通用解决方法,尤其是其中的结构型设计模式,通过继承机制或者对象组合的方式使得类和对象能够相互组合并构成更大的系统。所以提取结构型设计模式的相关信息能够帮助我们更加充分的理解系统。
2 识别过程
本论文中所研究的设计模式识别算法是基于抽象语法树静态分析的自动化识别。其基本方法如图1所示.
2.1 从源代码生成抽象语法树
本论文所提出的设计模式识别方法是基于源代码静态分析的。在本文的识别方法中,首先是根据源代码构建其抽象语法树模型。通过抽象语法树模型的建立,得到程序在更高抽象层面上的表示。再对抽象语法树进行分析,能够有效简化源代码分析的复杂度。抽象语法树的生成,基于第三方开源工具RECODER[3]来实现。
2.2分析抽象语法书得到设计模式候选实例
设计模式候选实例识别的过程,概括的说即是分析设计模式类图,分解类图中各角色的相互关系;根据分解关系设计算法流程搜索程序的抽象语法树模型,得到满足关系的设计模式候选实例的过程。
在本论文中,采用元组的方式来描述一个设计模式实例,即对于任何一个设计模式实例,采用Design Pattern:(Role A, Role B, Role C)
的形式来表达。
而在分析和分解设计模式类图各角色的相互关系时,本文只关注一下三种类型的关系,即继承、代理、组合关系。本文约定用这三种关系来表示一个设计模式所需要满足必要条件,同时采用如下表达式来表示继承、代理、组合关系:
1) 继承关系:Inheritance(Super Class, Sub Class)
2) 代理关系:Delegation(Delegator, Delegatee)
3)组合关系:Composition(Container, Containee)
具体地,对抽象语法树进行分析识别设计模式候选实例的过程,可以分解为如图2所示的三个步骤:
1)确定设计模式实例的元组表示
[1]中包含了所有结构型模式的结构图。而确定设计模式元组表示的过程,即是将结构图中除Client之外的所有角色表示为一个N元组。
2)分析设计模式类图并分解出各角色间的继承、代理、组合关系
继承关系和组合关系在UML类图中是非常明显的,可以直接找出。而代理关系则是通过两点判断:一、判断在类图中存在的依赖关系是否为代理关系,若是则直接找出;二、根据类图所给注释推断出隐含的代理关系。
3)設计候选实例识别算法流程
模式候选实例算法的起点均为遍历系统中所有的类。在遍历的过程中,根据类、对象间的关系逐步找到满足步骤2关系的元组。
在设计模式候选实例识别算法的设计过程中,需要遵循以下几个原则:
①根据类的继承层次自底向上分析
② 优先获取继承相关类
2.3约束条件检查
对已经识别出的实例进行进一步检查,以剔除其中不符合约束的实例。需要明确的一点是,候选实例识别的过程是从整个系统进行搜索;而约束检查则仅针对已经识别出的候选实例。
约束条件的检查过程如图3所示。
1)候选实例角色完备性约束检查
在文本所述设计模式候选实例的识别过程中,候选实例是根据类图的分解关系搜索抽象语法树模型得到的,可能会出现角色对应类为空的情况。所以,我们需要检查候选集中每个实例的角色完备性。
2)自身约束条件检查
对抽象语法树进行分析得到候选实例的过程,是根据类与对象间的相互关系进行信息提取、判断而得到设计模式实例的过程。这个过程,主要关注的是类与类的相互关系 ,而忽略了类本身的一些属性。所以为了增加识别的准确性,我们还需要从类自身的一些属性出发检查。
自身约束条件主要考虑以下两个方面:
① 访问权限修饰符
访问权限修饰符在编程语言中具体所指为public private protected 关键字。
在本文的方法中只检查角色对应类是否被public关键字所修饰,约定该约束使用表达式IsPublic( Class ) 表示一个类被public关键字修饰。
② 类类型
在本文中,类类型指的一个类(Class)是接口、抽象类还是具体类。
设计模式的类类型约束,可以直接通过设计模式类图得出。
3)不存在关系检查
候选实例的识别过程中,算法设计只考虑了设计模式中角色与角色之间的必要关系。除了存在的必要关系,在设计模式各角色间可能还有不存在关系。
同样的,在不存在关系的检查中,本文同样也只针对继承关系、代理关系和组合关系进行检查。
2.4 Adapter模式实例
本小节将以Adapter模式的识别过程为例具体阐述本文所论述的设计模式识别一般方法是如何变为具体的识别流程的。
3 实验
对本文提出的方法,我们在一些开源项目中进行了实验。在此,三种不同版本的JHotDraw项目(5.1, 6.0b1和7.0.6),和J2SE 5.0中的java.*包。
J2SE是Java 2标准版的缩写[4],其中包含构成Java语言核心的类。JHotDraw是一个二维GUI绘制的Java框架[5]。
本实验环节中对Adapter, Composite和Decorator三种模式做了实验,得到的结果如下:
4 结论与展望
本论文提出了一种结构型设计模式的自动化识别过程。旨在通过这样的方式来更好的支持对软件系统的理解。该方法首先将源代码转换成抽象语法树,并使用静态分析的方法对其进行分析以得到软件系统中的设计模式实例。
同时,本文使用提出的方法进行了实验,通过对实验环节得到的多组数据进行分析,验证了本文所述算法的能够较为有效的识别实际项目中存在的设计模式实例。
本论文虽然提出了一个通用的结构型设计模式识别的通用算法设计原则和流程。但是对于每一种设计模式的具体设别过程,依旧需要具体模式具体分析。所以,在之后的研究中希望能够进一步增强算法的通用性,由此来提高该自动化识别方法的可扩展性。
参考文献:
[1] Gamma E,Helm R,Johnson R,et al.Design Patterns: Elements of Reusable Object-Oriented Software[M].Addison-Wesley,1995.
[2] Pacione M J,Roper M,Wood M.A novel software visualisation model to support software comprehension[C].Reverse Engineering Proceedings.11th Working Conference on,2004:70-79.
[3] RECODER Main Page[EB/OL].http://recoder.sf.net.
[4] J2SE 5 Source Code[EB/OL].http://www.oracle.com/technetwork/java/javase/downloads/index.html.
[5] JHotDraw Start Page[EB/OL].http://www.jhotdraw.org.