计算机编程/面向切面编程
一位维基教科书用户建议将此书籍或章节 合并 到 编程语言/面向切面语言。 请在 讨论页面 上讨论是否应该进行合并。 |
面向切面编程 (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 语言的扩展。在本示例中,将使用该语言。