跳至内容

计算机编程/面向切面编程

来自维基教科书,开放书籍,开放世界

面向切面编程 (AOP) 是对面向对象编程 (OOP) 的后续发展,旨在解决 OOP 的一些实际局限性。

OOP 旨在通过将数据和方法封装到离散对象中来管理软件开发的复杂性,减少不同软件构造之间的依赖关系,以及多态性,即能够将不同的程序构造视为特定目的的相同构造的能力。总体而言,定义一组构造良好的对象,这些对象之间具有明确的关系,允许程序员将软件“组件化”,以小规模、简单、专注的方式工作,创建易于安全地组合成更大构造以实现更大功能的构造。

OOP 的实际困难在于,在任何大型应用程序中,都有一些方面不容易分解成对象/组件,或不容易作为对象/组件使用。“横切关注点”或 *横切* 是一个大型软件项目的组成部分,它们在几个地方或多个对象中以相同的方式存在,在这些地方,实现代码来有效地解决这些关注点会破坏封装,增加而不是减少依赖关系。AOP 旨在通过将处理这些横切关注点的代码移动到单独的编程构造中来减少依赖关系和复杂性,这些构造然后可以由 *编织器* 以自动方式编织回 OOP 源代码中。结果是面向对象代码,然后可以像平常一样进行编译。

AOP 的一个典型应用是日志记录。通常,程序员会使用日志记录来记录程序的状态和流程,这既便于在开发期间进行调试,也便于在部署后进行错误修复。在 OOP 程序中,这有几种可能的实现方式

  • 每个对象都可以访问全局日志记录对象,并调用其方法来记录事件或状态。
  • 所有需要日志记录的对象都重复相同的代码来写入日志。
  • 每个对象都保存自己的日志,可能写入文件。

这里 AOP 试图解决的本质问题是,代码在几个地方重复出现,这使得维护变得困难,并且增加了不同构造之间的依赖关系。更改日志记录器的行为需要在第二种和第三种情况下在多个文件中重写相同的代码;更改日志记录器的使用需要在所有情况下重写相同的代码。

通过将日志记录定义为横切关注点并使用切面来解决问题,程序员编写切面代码来处理日志记录,并使用 *编织器* 将代码注入 OOP 源代码,然后像平常一样编译 OOP 代码。日志记录功能已从类的源代码中移除,放置在一个位置,并被视为另一个可以在本地定义和实现的单一构造,然后可以离散地用于程序的其余部分。

在理论方面,AOP 是实现 *关注点分离* 的方法。对象经常被要求处理几个概念上不同的关注点。销售条目应用程序中的发票包含一些显而易见的属性,例如购买者的身份和购买的商品;但发票对象也可能需要知道如何记录其操作,如何将其持久化到数据库中,如何验证购买者的信用额度,以及如何在其到期后发出标志。因此,发票类可能变得很大、复杂且难以维护。每个关注点对于该类来说都是合法的,但根据 OOP 的原则,必须在内部和不可见地进行处理。如果这些关注点由其他关系不太密切的对象共享,那么不仅涉及的类具有不必要的复杂性,而且这种复杂性在多个地方重复出现。

一些定义将有所帮助

*横切关注点* 或 *横切* 是 OOP 应用程序设计中的任何部分,这些部分同时出现在 OOP 应用程序的几个不同部分中,而这些部分之间没有其他关系。日志记录是一个明显的例子,但持久性是另一个例子:在银行应用程序中,许多不同的对象必须以相同的方式存储和检索(例如,关系数据库)。持久性是应用程序对象的横切关注点。

*连接点* 是 OOP 代码中语义上可定义的点,编织器可以识别这些点。对于我们的日志记录示例,程序员可能希望记录调用堆栈,因此日志记录器应记录每个函数的入口和出口。

一组连接点由 *切入点* 共同识别:连接点是编织器识别的代码中的实际位置;切入点是定义要查找的连接点的 AOP 代码。

切入点不仅识别连接点,还包括对这些点采取行动的代码。该代码称为 *通知* 或 *通知*。

那么,*切面* 是一组切入点,用于定义要由 AOP 模块处理的特定横切关注点。在实践中,我们对日志记录示例的解决方案是一个切面模块,它定义切入点,以识别程序员希望进行日志记录的那些连接点。识别了连接点后,程序员将在 AOP 模块中编写通知,编织器将该代码注入 OOP 源代码作为代码编译的预备步骤。

此时,看起来 AOP 无非是将实用程序代码从类中提取出来并集中起来;这是 AOP 的优点之一。但是,AOP 可以分离更复杂的关注点。在我们的发票示例中,我们提到发票有到期日。同样,我们自己的应付款项也可能有一个到期日。这种“到期”关注点可以封装为一个切面,该切面在发票和应付款对象的构造或初始化时定义切入点。在这些连接点,可以向两个类添加到期日成员,以及将发票/应付款注册到到期监控系统中的代码,该系统会生成即将到期的日期的每日报告。跟踪付款期限的代码已移至单个模块,降低了发票/应付款对象的复杂性,消除了发票/应付款类与期限监控系统之间的依赖关系,并且使得维护和更改系统变得更容易。

目前,AOP 最流行的平台是 AspectJ,它是 Java 语言的扩展。这里将使用这种语言作为示例。

华夏公益教科书