网站首页 新闻首页 网页设计图形动画软件编程网站开发办公软件操作系统数据库网络技术认证考试范文资料黑客攻防 书籍教程 进入论坛

面向方面的编程:它的好处是什么?

http://www.diybl.com/ 2008-3-16  网络 点击:  [ 评论 ]
文章搜索:    【点击打包该文章】

Gary Pollice, Professor of Practice, 伍斯特工学院

2006 年 3 月 15 日

来自于 Rational Edge:关于面向方面的编程的大多数介绍,都是建立在技术可行的有限环境的基础之上,而忽略了AOP的实际价值。这篇文章提供了将AOP技术应用于软件开发项目的一系列实际的例子。

 最近,我被要求领导我们软件工程研究小组(SERG)开一个关于面向方面的编程(AOP)的讨论。在会议开始前的几小时,一个学生问我:“那么,方面的好处是什么?但是不要给我关于日志的例子。那似乎是我阅读关于方面的东西时,唯一看见的东西。”

他的问题促使我停下来,并考虑将AOP应用于一些正在做的软件系统的有效方法。他同时也使我认识到需要如何和什么时候采用新的方法,尤其是当他们需要一个新的思考方式时。AOP,我之前在这个专栏已经谈论过,它似乎代表了一个新方法。我想谈论一些我认为AOP可以被(或已经被)有效使用的方法。同时我们将看到一些可能有助于AOP推广的最新进展。

我将在讨论中使用面向方面的Java作为例子。然而,当今有很多种面向方面执行的可用语言。这些语言包括AspectC++甚至于AspectL,它是一种面向方面的Lisp执行语言。 1

AOP概念的回顾

如果你不熟悉AOP,有很多关于它的介绍文章,包括我2004年2月发表的的文章。 2 很多,也许不是全部,关于AOP的介绍使用日志作为一个例子来说明方面的概念。(日志是很多人都懂的东西,并且它是AOP可以被如何使用的一个很好的例子。)方面的关注点是横切。那就是说,它们不能被简单地归为一类。但是,如果我们严格按照面向对象的范例,我们需要将这些业务重新整合为一个统一的,可维护的方式。通常,横切的责任被委派给一个单独的帮助者类,并依靠每一类来要求由方面表达出的功能性,包括在合适的地点进行调用。保证开发人员始终在编码的合适点上插入登陆是较难实施的。方面提供了一个机制来改善这种状况,尽管它还不完美。

有一些概念你需要知道以便你理解这篇关于AOP的讨论。主要概念就是连接点。这是一个所有编程人员都熟悉的概念,但我们现在有一个新名字给它。一个连接点是:一个在程序流程中定义明确的点。 3 连接点有很多类型,正如一个方法的调用或一个方法的返回,都可以是一个正常的返回或者抛出一个异常。

使用AOP,我们需要一个在一个程序中识别连接点的方法。AspectJ使用切入点来描述一个或更多的连接点。切入点是一个用来描述一套连接点的表达式。你可以把切入点想象成对你的编码的一个查询,用它来返回一系列的连接点。

当你选择一系列连接点的时候,你可以为它们提供参考建议。参考建议是一种可执行的编码,当连接点遭遇到程序运行时,它就需要运行。连接点,切入点和参考建议关注于你的软件的动态属性。参考建议改变了程序编码的运行特性。

有一个可以处理你的系统的静态特性。就是类型间声明。类型间声明允许你改变一个程序的动态结构。你可以增加程序和变量,并根据特殊的规则改变继承性层次。

正如类是Java模块化的单元,方面是AspectJ模块化的附加单元。方面封装了一个横切关注点的连接点,切入点,类型间声明和参考建议。AOP不是面向对象分析和设计的一个替代。它通过处理许多面向对象方法不能充分提供最合适方案的情形,构建了面向对象的范例。

AOP实例

现在让我们来看看AOP可以在何处使用的一个实例。一些实例可以在生产系统中找到,而另外一些可以在生产和开发环境中找到。让我们从开发人员的一对实例开始吧。

执行追踪

我惊讶于如此多的开发人员将某些类型的打印语句放入他们的编码中,来调试或跟踪一个程序的执行。我发现调试程序善于给出信息。但我们不在这里讨论了解你的调试程序的价值。当然,想要生产一些你的程序的文本跟踪信息,是有一些合理原因的。在Eclipse当前的一套AspectJ Development Tools(AJDT)中有一个关于方面的很好的实例,那个方面实现了一个程序执行跟踪的过程。在Eclipse的帮助中,有关于这个实例的详细描述。你可以在AspectJ Programming Guide中找到它。

实例有一个小Java应用程序,它有很多类来表现二维图形,就像圆形和方形。同时它还有一个主要程序来创建两个圆形和一个方形,并打印出它们的方面,诸如面积,周长,以及它们中心点间的距离。当你运行程序时,你将得到如图1所示的输出结果。

Figure 1: Input from the shape program

图1:从形状程序的输入

如果我们想看见程序调用的真实顺序,我们有两个选择。第一种方法是,我们可以在每一个程序的开始插入编码,那样可以以程序和类的名字打印一个信息,并且事实上程序已经被输入。我们需要为每一个程序做上述的过程。第二种方法是,我们要创建一个方面来做完全一样的事情。用这种方法,我们不需要改变应用程序的任何编码。

跟踪实例包含使用方面跟踪解决方法的几个版本。我们来看最终的版本。其他版本的讨论请见AspectJ Programming Guide中的讨论。

一个稳固的跟踪机制的解决方法包含两个文件。第一个是一个抽象的方面。一个抽象的类的一些编码被留给了编程人员,编程人员使用它在一个导出的类中执行,或者在一个导出的方面中执行。这个抽象的方面,叫做Trace,有几种标准程序来打印关于输入和退出一个程序,或构造方法的信息以及格式化输出的结果。如果我们没有使用方面,这些程序将在一个帮助者类中,你可以用它来输出跟踪信息。Trace同时允许编程人员通过设置一个叫做TRACELEVEL的性质,来设置跟踪的类型。这里有三个级别:没有信息,没有缩进的信息,以及被缩进来表达被嵌套的调用的信息。

跟踪定义了三个切入点;其中的两个是具体的,一个是抽象的,正如图2所示。抽象的切入点是myClass,它必须通过可以扩展Trace的方面来提供。切入点的目的是为包含将被建议的连接点的对象选择类。这个让开发人员决定哪些类将被包括在跟踪输出结果中。

Figure 2: Pointcuts in the trace aspect

图2: 跟踪方面中的切入点

myConstructor切入点在任何构造方法的开始,它被myClass选择为类中的一个对象选择连接点。连接点是实际的主体。myMethod与myConstructor相似,但它在一个被选择的类中选择任何程序的执行。注释同样省略了toString程序的执行,因为它被用在了建议中。

方面提供的建议相当简单。在每一个连接点之前被插进的建议在连接点之后执行。这个如图3所示。

Figure 3: Advice in the Trace aspect

图3: Trace方面中的建议

为了使用Trace方面,你需要扩展它,并为抽象的切入点提供一个具体的执行。图4所示的是实例程序TraceMyClasses方面的实体。切入点只选择TwoDShape,Circle或Square实例的对象。主要程序设置TRACELEVEL,初始化跟踪流,以及运行实例的主要程序。

Figure 4: Concrete tracing aspect

图4: 具体的跟踪方面

图5所示的是来自于运行实例部分的输出结果。注意:输出结果打印关于每一个对象的信息。这是每一个对象的toString程序的一部分。既然myClasses切入点公布对象到建议,那么建议就可以轻易地增加关于对象的信息。

Figure 5: Example trace output

图5: 跟踪结果举例

使用AOP方法进行跟踪比在需要的地方人工的插入跟踪代码有以下几条好处。

  • 你只需要在一个(两个方面)地方放置你所有代码需要的用于跟踪的功能。
  • 插入和删除跟踪代码是很容易的。你可以轻易地从构建配置中删除方面。
  • 在任何你需要的地方跟踪代码,即使你增加了新的方法到目标类。这可以消除人为的错误。同时你知道所有跟踪代码被删除了,并且当你从构建配置中删除方面时不会忽略任何东西。
  • 你有一个可重复使用的方面,它可以被应用和升级。

契约式设计或防御性编程

Bertrand Meyer介绍了契约式设计的概念。 4 这个原理声称一个类的设计者和这个类的使用者,共同分享关于类的实现的假设。合同包括不变量,先决条件和后置条件。契约式设计让类的设计者专注于实现了类的功能性的逻辑,而不用担心实参的有效性。当然,前提是合同规定了实参的先决条件。契约式设计避免了额外的编码并提高了性能,只要所有的客户都遵守契约。

欢迎光临DIY部落,点击这里查看更多文章教程   【点击打包该文章】
如果图片或页面不能正常显示请点击这里 站内搜索:   

文章评论

请您留言