面向方面编程中必要语义约束的研究
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
面向方面编程中必要语义约束的研究1
杨剑青,杨宗源,谢瑾奎
华东师范大学计算机科学技术系,上海 (200062)
E-mail:learwwj@
摘要:面向方面编程(AOP)可以很好地解决非功能性关注点(Non-Functional Concern)的封装问题,但是目前的AOP技术过于灵活,甚至会不恰当地破坏原有对象的封装性,以及代码正确性。本文讨论了在软件设计或者编程实现过程中,对于AOP应该加以适当约束,具体包括常量性质的约束,单件(Singleton)类型的约束等等,在各个不同的具体应用领域中,还可以相应有不同的约束,通过这些约束,AOP才能更好地为软件开发所服务。
关键词:AOP;约束;软件开发;软件工程
中图分类号:TP311
1.引言
面向方面编程(Aspect Oriented Programming,以下称为AOP)可以用来解决软件开发中,对于系统级关注点实现的代码纠缠和难以管理等问题。但是对其任意使用可能在某些情况下,造成对原有面向对象模型语义的破坏,本文提出了在现有的AOP实现机制上,添加适当的约束来解决这一问题,并且刻画出了所提出约束的设计模式。
2.AOP简介
面向对象方法已经在软件工业界取得了巨大的成功。面向对象方法通过把不同大小级别的功能单元封装在类中,来提高软件的开发效率。但是,对于一些系统级别的,非功能性的关注点(Non-Functional Concern),比如操作同步,资源的互斥,数据加密解密,数据的压缩解压缩等等,面向对象技术的解决方案却会引入一系列的问题,比如代码纠缠(Code Tangling)和难以管理[2]。
所谓代码纠缠,就是指相同的代码反复地出现在不同的类中,而没有办法使用面向对象方法(比如继承)加以消除;而难以管理主要指的是面向对象技术只提供了封装功能关注点的单元,而没有提供封装横切关注点(Cross-Cutting Concern)的单元,导致这些关注点的修改十分困难。AOP的方法对于解决上述问题能够提供极大的帮助,使用AOP的方法,开发人员可以显式地捕捉横切关注点的结构,将横切关注点封装为一个单独的实体,并且可以便捷地修改实现横切关注点的代码,下面结合最常使用的AOP实现,AspectJ (/ajdt)来简单介绍一下AOP中的一些重要概念[3]:
a. Join Point是在程序的执行流程中具有良好定义的点,AspectJ提供几种不同类型的Join Point,方法调用Join Point,域设置Join Point以及异常抛出Join Point。比如calls(void Rectangle.setWidth(float))定义了所有在Rectangle对象上,对方法setWidth的调用。
b. Pointcut是Join Point的集合,比如Pointcut setArea() : calls (void Rectangle.setWidth(float)) || calls(void Rectangle.setLength(float)),定义了所有在Rectangle对象上,对方法setWidth和setLength的调用。
c. Advice是当程序执行到Pointcut时所运行的代码。Before Advice在程序运行到Join Point,计算执行之前运行;After Advice在Joint Point结束,计算执行之后运行;Around Advice 在程序执行到Join Point时开始运行,并且对该Join Point的计算是否确实运行有显式的控制。
1本课题得到高等学校博士学科点专项科研基金(项目编号:20060269002)的资助。
d. Introduction 是一种可以向类中添加新的域,以及改变类的继承关系的机制,但和Advice 有所不同,Introduction 是在编译时静态实现的。上文介绍的一些概念,就是在使用AspectJ 进行AOP 开发时经常使用到的一些编程实体,下面就结合一个具体的实例,提出无约束地使用这些元素所带来的问题。
3. 无约束AOP 引起的问题
3.1问题描述
任意地使用AOP 中提供的各种机制,有可能会引起一系列的副作用。比如没有约束地使用AOP 会严重地破坏原有面向对象模型的封装性,改变原有对象中域的值以及方法的执行流程,从而导致了原有对象的语义发生变化。下面所要给出的一个实例就是通过使用AOP 来改变了原有对象的行为,从而使程序中出现了难以发现的错误。
3.2实例
实例中的原有类(即实现功能关注点的类)是一个结构十分简单的类Rectangle ,其中只有两个分别代表长和宽的域width 和length ,以及这两个域的setter 和getter 方法,实现功能性关注点的方法是getCircumference 和getArea 分别计算类Rectangle 的周长和面积。Rectangle 的类图如下所示:
图1 Rectangle 的类图
BadAspectDemo 中只有一个main 方法,简单地构造一个Rectangle 类的对象,然后设置width 和length 的值,最后调用它的getCircumference 方法和getArea 方法,以及输出计算结果。具体代码如下所示:
public class BadAspectDemo {
public static void main(String[] args) {
Rectangle r = new Rectangle();
r.setLength(4);
r.setWidth(5);
System.out.println(r.getCircumference());
System.out.println(r.getArea());
}
}
在没有使用AOP 技术的情况下,这段程序的输出结果一目了然,必定是18.0以及20.0,但是在采用了AOP 对Rectangle 中的一些方法进行了增强以后,输出结果就会发生十分微妙的变化。