FRAMINGHAM (10/03/2003) - To understand aspect-oriented programming (AOP), let's first take a look at two models of labor union organization in the U.S. The old American Federation of Labor (AFL) organized workers vertically, according to their particular craft or trade. Thus, a large company might have dozens or hundreds of unions to deal with, each representing a specific group of workers. The younger Congress of Industrial Organizations (CIO), on the other hand, organized a single union for all workers in a given industry regardless of their individual trades.
Under the AFL approach, each separate craft union needed its own officers and organizers, and each would have to negotiate separately with management. The CIO's horizontal approach, however, cut across the different trades; it could provide similar services and benefits for all workers in a company en masse.
Traditional programming methodologies, even structured and object-oriented approaches, are vertical or hierarchical in nature, like the AFL model. For any given application, there are a number of common operations that, because of minor differences in their logic, the way they're handled, the other modules they interact with or the data they use, must be programmed separately. With AOP, the idea is to look at these operations and abstract them in such a way that they can be called from anywhere.
AOP uses a new type of software module, called an aspect, that cuts across traditional classes and organizational models. The essence of AOP is that every object-oriented program, well designed or not, contains some method calls that appear in several places throughout the program.
Method calls transfer control to a specific closed subroutine within a program. If you change the call to a particular method or its error-handling routine, you may need to make changes in every occurrence of this call ó potentially requiring hundreds or thousands of manual edits. Such crosscutting typically occurs in distribution, synchronization, failure handling, policy enforcement and performance optimization, as well as in a number of common design patterns.
Prior to AOP, developers found it difficult to deal with this crosscutting behavior, because separate pieces of identical or nearly identical code were scattered throughout many different modules. AOP lets you program an aspect once and then reuse it. AOP encapsulates behaviors that affect multiple classes into reusable modules. A code weaver (which can be an interpreter, compiler or preprocessor) then combines the aspects and the classes appropriately.
Some developers have been concerned because when you make a change in an aspect, there's generally no simple way to know which modules will be affected by it. But AOP integrated development environment extensions address this problem, making it possible to browse the crosscutting structure of aspects.
From their earliest days, programming languages and methodologies have used various kinds of modular construction, such as subroutines, functions, procedures and objects.
Modularity made programs easier to write and debug and allowed reuse of sections of code. Previous forms of modularity are, however, primarily hierarchical layers of procedure libraries, object-oriented class graphs and others. AOP adds to this the ability to work with a modular structure that cuts across these hierarchies.
Another way to look at AOP programming is by relating it to dimensionality. Procedural programming deals with all concerns in a line. Though we can move pieces of code into different functions, the main stream still controls the entire process. This is the linear, one-dimensional model.
When object-oriented programming is introduced, we can present the world in computer language in a more natural way by describing different objects and their functions. Connections between different objects form a network. We can think of this as a 2-D model.
AOP recognizes that this model needs more dimensions, because crosscutting or distributed code can be seen as making extra connections that can't be mapped in a 2-D space. AOP connects program components in a 3-D way without disrupting existing connections and relationships.
Kay is a Computerworld contributing writer in Worcester, Massachusetts. Reach him at email@example.com.
An AOP Glossary
Advice: Code that runs after certain conditions are met. Advices allow you to transparently apply things like logging and metrics to an object model.
Aspect: A construct, resembling classes, for addressing concerns that cut across classes. An aspect can contain methods and fields, extend other classes or aspects, and implement interfaces.
Concern: Some functionality or requirement necessary in a system that may or may not have been implemented in a code structure. Concerns can range from high-level notions like security and quality of service to low-level notions such as caching and buffering. They can be functional, like features or business rules, or systemic, such as synchronization and transaction management.
Crosscutting: Two concerns crosscut if the methods related to those concerns intersect. An aspect crosscuts the traditional class and method boundaries by applying the same code in each.
Interceptor: Used to implement an advice in JBoss 4.0, a popular Java application server.
Introduction: A way to add methods or fields to an existing class, to bring multiple inheritance to plain Java classes or to attach a new API to an existing object model. Used in JBoss 4.0.
Joinpoints: Points, or hooks, in a program's execution where enhancements can be added or behaviors attached. For example, joinpoints could define calls to specific methods in a class.
Metadata: Additional information that can be attached to a class or a given instance of an object, either statically or at runtime. Metadata helps when writing truly generic aspects that can be applied to any object, but the logic needs to know class-specific information.
Pointcuts: Program constructs that designate joinpoints and collect specific context at those points.
Weave: To assemble an individual concern into a process by interlacing different execution-logic fragments according to some supplied criteria.