许多 Java 开发人员已经接受了面向方面编程(AOP)的非强制性风格和灵活性,特别是在用于建立高度松散和可扩展的企业系统时。在本文中,您将看到 AOP 的功能设计概念之一(静态横切)如何把可能是一大堆混乱的紧密耦合的代码转变成一个强大的、可扩展的企业应用程序。
在将商业需求转换成软件功能的快速开发周期中,面向方面是一种可以利用的强有力的设计原理。通过将首要的设计重点从面向对象编程(OOP)的传统化特性转移出来,AOP 和设计原理允许软件架构师用一种和面向对象相当而又互补的方式来考虑设计。
在本文里,您将学习如何实现 AOP 中最没有得到充分利用的特性之一。横切(crosscutting)是一种蕴含强大力量的相对简单的设计和编程技术,尤其是当它被用于建立松散耦合的、可扩展的企业系统时。虽然动态横切(其中对象的运行时行为可以改变)被认为是 AOP 的根基之一,但静态横切却是一种远不为人所知的技术。我将在本文中尝试弥补这个缺憾。我将首先概述动态和静态横切,然后迅速切入一个实现场景来展示后一种技术。您将亲自体会到静态横切是多么方便地克服了如下这个最常见的企业挑战之一:如何在利用第三方代码的同时保持应用程序代码库(codebase)的灵活性。
请注意,尽管我首先简要地从概念上概述面向方面编程,但本文并不是一篇关于 AOP 的介绍。请参阅 参考资料 一节以获得关于该主题的介绍性文章的列表。
面向对象设计最根本的魅力在于,它能够将真实世界领域中的实体及各自的行为建模为抽象的对象。以面向对象方式设计的系统产生了很多有效的业务对象,比如 Person
、 Account
、 Order
以及 Event
。面向对象设计的缺点在于,这样的业务对象会因为混合的属性和与对象最初意图不一致的操作而变得混乱。
通过使设计者运用动态和静态横切,用一种非强制性的整洁和模块化的方法来添加对象行为,面向方面编程有效地解决了这一问题。
![]() ![]() |
![]()
|
横切 是面向方面编程的专有名词。它指的是在一个给定的编程模型中穿越既定的职责部分(比如日志记录和性能优化)的操作。在横切的世界里,横切有两种类型:动态横切和静态横切。在本文中,尽管我将简要地同时讨论二者,但我主要关注静态横切。
动态横切 是通过 切入点 和 连接点 在一个 方面 中创建行为的过程,连接点可以在执行时横向地应用于现有对象。动态横切通常用于帮助向对象层次中的各种方法添加日志记录或身份认证。下面让我们花点时间了解一下动态横切中的一些实际概念:
- 方面(aspect)类似于 Java 编程语言中的类。方面定义切入点和通知(advice),并由诸如 AspectJ 这样的方面编译器来编译,以便将横切(包括动态的和静态的)织入(interweave)现有的对象中。
- 一个 连接点(join point) 是程序执行中一个精确执行点,比如类中的一个方法。例如,对象
Foo
中的方法bar()
就可以是一个连接点。 连接点是个抽象的概念;不用主动定义一个连接点。 - 一个 切入点(pointcut) 本质上一个用于捕捉连接点的结构。例如,可以定义一个切入点来捕捉对对象
Foo
中的方法bar()
的所有调用。和连接点相反,切入点需要在方面中定义。 - 通知(advice) 是切入点的可执行代码。一个经常定义的通知是添加日志记录功能,其中切入点捕捉对对象
Foo
中的bar()
的每个调用,然后该通知动态地插入一些日志记录功能,比如捕捉bar()
的参数。
这些概念是动态横切的核心,虽然正如我们即将看到的,它们并不全都是静态横切所必需的。请参阅 参考资料 来了解关于动态横切的更多内容。
静态横切 和动态横切的区别在于它不修改一个给定对象的执行行为。相反,它允许通过引入附加的方法字段和属性来修改对象的 结构。此外,静态横切可以把扩展和实现附加到对象的基本结构中。
虽然现在还无法谈及静态横切的普遍使用——它看起来是 AOP 的一个相对未被探索(尽管非常具有吸引力)的特性——然而这一技术蕴含的潜力是巨大的。使用静态横切,架构师和设计者能用一种真正面向对象的方法有效地建立复杂系统的模型。静态横切允许您不用创建很深的层次结构,以一种本质上更优雅、更逼真于现实结构的方式,插入跨越整个系统的公共行为。
在本文剩下的篇幅中,我将重点讲解静态横切的技术和应用。