Aspect-oriented programming
|
In Software Engineering, the programming paradigm of aspect-oriented programming (AOP) (also called aspect-oriented software development (AOSD)) attempts to aid programmers in the Separation of concerns, or the breaking down of a program into distinct parts that overlap in functionality as little as possible. In particular, AOP focuses on the Modularization and Encapsulation of Cross-cutting Concerns.
The concept was originally introduced by Gregor Kiczales and his team at Xerox PARC. This team also developed the first, and still most popular, AOP language: AspectJ.
Prior programming methodologies including Object-oriented programming and Procedural programming similarly focus on the separation and encapsulation of concerns (or any area of interest of focus) into single entities. For example, classes, procedures, packages, and methods all help programmers encapsulate concerns into single entities.
Although these methodologies can successfully encapsulate many software concerns, there are some concerns that defy such easy encapsulation. These are called Crosscutting Concerns because they exist in many parts of the program.
The prototypical crosscutting concern is Logging. This is because a logging strategy necessarily affects every single logged part of the system. Logging, thereby crosscuts all logged classes, methods, and procedures.
Typically, an implementation of an AOP language seeks to encapsulate these types of crosscutting concerns through the introduction of a new construct called an aspect. An aspect can alter the behavior of the base code (the non-aspect part of a program) by applying advice (additional behavior) over a quantification of join points (points in the structure or execution of a program), called a pointcut (a logical description of a set of join points).
In many AOP languages, method executions and field references are all examples of join points. A pointcut may be, for example, all references to a particular set of fields.
Contents |
Motivation and Basic Concepts
The core idea of Aspect-Oriented Programming is to enable a better separation of concern, by allowing the programmer to create cross-cutting concerns as first-class program modules. Cross-cutting concerns are those parts, or aspects, of the program that in standard design mechanisms end up being scattered across multiple program modules, and tangled with other modules.
For example, consider a banking application. The method for transferring an amount from one account to another is conceptually very simple:
void transfer(Account fromAccount, Account toAccount, int amount) { if (fromAccount.getBalance() < amount) { throw new InsufficientFundsException(); } fromAccount.withdraw(amount); toAcount.deposit(amount); }
(the examples are shown in a Java-like syntax, since at the time of writing, an overwhelming majority of AOP-related research and work is done in Java or Java-variants.)
However, in a real-world banking application, this transfer method is far from being sufficient. We must include security checks to verify that the current user is authorized to perform this operation. We must enclose the operation in a database transaction, to prevent accidental data loss. We must log the operation to the system log. And so on. A very simplified version with all those new concerns would look somewhat like this:
void transfer(Account fromAccount, Account toAccount, int amount) { if (!getCurrentUser().canPerform(OP_TRANSFER)) { throw new SecurityException(); } Transaction tx = database.newTransaction(); if (fromAccount.getBalance() < amount) { tx.rollback(); throw new InsufficientFundsException(); } fromAccount.withdraw(amount); toAcount.deposit(amount); systemLog.logOperation(OP_TRANSFER, fromAccount, toAccount, amount); tx.commit(); }
The code is no longer simple and elegant. This is because the various new concerns are tangled with the basic functionality (sometimes called the business logic concern). The transactions, security, logging, etc. are all examples of cross-cutting concerns.
Also consider what happens if we suddenly need to change, e.g., the security considerations for the application. In the program's current version, security-related operations are scattered across numerous methods, and such a change would require a major effort.
Therefore, we find that unlike the core concerns of the system, the cross-cutting concerns are not properly encapsulated in their own modules. This increases the system complexity and makes maintainance considerably more difficult.
AOP attempts to solve this problem by allowing the programmer to develop cross-cutting concerns as full stand-alone modules. These modules are called aspects. In most AOP languages, an aspect is comprised of one or more advice, which are code snippets (like methods), and a list of join points, which are points in the main program onto which the advice should be weaved. For example, a security module can include an advice that performs a security check, with instructions to weave this code snippet into the beginning of methods a(), b() and c() of some class. Powerful mechanisms are deployed to enable a broad specification of join points, so that weaving destinations will not be enumerated manually by the developer. These mechanisms are commonly known as pointcut specification languages.
Join Points and Pointcuts
To make an aspect useful, the developer must specify exactly where in the program each of its advice must be woven. Possible weaving destinations are known as join points, which are well-defined points along the execution of a program. Join points can include:
- Method execution
- The instantiation of an object
- The throwing of an exception
- The catching of an exception
- Access to a field (data member)
- ... etc.
However, manually enumerating all the target join points for each advice would be tiresome and bug-prone, and thus render the whole concept of AOP meaningless. To overcome this problem, AOP languages use pointcuts, which are expressions that list join points. While a pointcut can be a simple list of specific join points, it can also be a logical expression, using such tools as regular expressions, boolean operators, and so forth. For example, the following pointcut definition (in AspectJ syntax):
execution(* MyClass+.get*(..) ) || get(* MyClass+.*)
will match the exection of any method, whose name starts with "get", in the class MyClass or any of its subclasses, as well as any read access to a field (private, public or other) in MyClass or any of its subclasses.
Such an expressive language allows developers to provide a broad specification that will automatically be used to enhance (by code weaving) existing as well as future classes.
The set of supported join points, and the expressiveness of the pointcut specification language, are among the features that differentiate various AOP languages from one another. Whereas some languages (like AspectJ) use a Java-like syntax for specifying pointcuts, others (such as AspectWerkz) use an XML-based syntax; and there are still other alternatives.
Weaving
The final challenge of any AOP solution is weaving, i.e., injecting the advice presented in aspects into the specified join-points associated with each advice.
In the original introduction of AOP, Kiczales and his team listed the following possibilities for weaving:
- A source pre-processor (similar to the original implementations of [[C++]]).
- A post-processor that patches binary files.
- An AOP-aware compiler that generates woven binary files.
- Load-time weaving (e.g., in the case of Java, weave the relevant advice as each class is loaded into the Java virtual machine (JVM)).
- Run-time weaving (trap each join point at runtime, and execute all relevant advice).
The first two options complicate the development process, whereas the last two options are likely to slow down the program's execution. The last option (run-time weaving) also requires a special execution environment, which is aspect-aware. In the world of Java, this implies a special JVM.
AspectJ's current solution is to use a dedicated compiler. The compiler generates standard Java binary class files, which can be executed by any standard JVM.
All of these weaving solutions (except the last) imply changing the code at some point; the code generated for a given Java class by the compiler, after processing and/or loading, is not what a standard Java compiler would have generated, since it now contains woven pieces of advice code. This is viewed by many as a major drawback of AOP, because it compilcates both the programmer's understanding of the program execution model and the use of any standard, existing tools, such as debuggers (see also "Problems", below).
A novel alternative was presented by Cohen and Gil, which present the notion of deploy-time weaving (http://www.forum2.org/tal/AspectJ2EE.pdf). This basically implies post-processing, but rather than patch the generated code, they suggest subclassing existing classes so that the modifications are introduced by method overriding. The existing classes remain untouched, even at runtime, and all existing tools (debuggers, profilers, etc.) can be used during development. A similar approach has already proved itself in the implementation of many J2EE application servers, such as IBM's WebSphere.
AspectJ: an AOP language
AspectJ is the most popular AOP language and it is an extension to Java and developed at Xerox PARC by Chris Maeda, who originally coined the term "aspect-oriented programming" (no one remembers exactly when). Gregor Kiczales coined the term "cross-cutting". The Xerox group's work was integrated into the Eclipse Foundation's Eclipse Java IDE in December 2002. This helped AspectJ become one of the most widely-used aspect-oriented languages.
All valid Java programs are also valid AspectJ programs, but AspectJ also allows programmers to define aspects. Aspects can contain several entities unavailable to standard classes. These are:
- inter-type declarations — allow a programmer to add methods, fields, or interfaces to existing classes.
- pointcuts — allow a programmer to specify a set of joinpoints (points in the execution of a program). All pointcuts are boolean expressions (quantifications) that evaluate to
true
whenever a matching joinpoint occurs. An example pointcut is:
execution(* *.set*(..) ) && this( *..Point)
- This pointcut evaluates to
true
whenever any method that begins with the letters set executes and the currently executing object is of typePoint
.
- advice — allow a programmer to specify what actions to perform when a pointcut evaluates to true. The actions can be performed before, after, or around the specified join point.
AspectJ is tightly integrated with a powerful set of tools, called AJDT, which assist developers in the understanding of how aspects and base code interact.
In March 2005, the AspectWerkz merged with AspectJ to form a single language. Other commercial Aspect-oriented frameworks include JBoss and Spring AOP.
AOP and other programming paradigms
Aspects emerged out of object-oriented programming and have functionality similar to meta-object protocols. Aspects relate closely to programming concepts like subjects, mixins, and delegation.
Mathematically, aspects are a second-order extension of any programming paradigm: while usual programming paradigms allow reasoning about single functions, messages and so forth by a function/message signature, AOP enables reasoning about entire sets of those entities by using pointcuts with wildcards in their signature. Thus one could view AOP as a powerful, logical extension, rather than an independent paradigm. Friedrich Steimann, for example, has proposed such a view.
But AOP proponents promote it as an external package shippable along with some application. For example, if a program itself has no support for security, an AOP package can serve as a modular extension to the application, providing security.
Other commercial implementations of AOP languages and frameworks include: AspectWerkz (recently merged with AspectJ), JBoss AOP, and Spring AOP.
Problems for AOP
One of the greatest problems for AOP is debugging. While at the syntactic level AOP program code appears separate, at run-time it is not. Concern-weaving can become unpredictable if it is not specified which aspect should dominate. Designers have considered alternative ways to achieve separation of code, such as C#'s partial types. However, such approaches lack a quantification mechanism enabling programmers to reach several join points of the code with one declarative statement.
Implementations
- For Java:
- AspectJ (http://eclipse.org/aspectj/)
- AspectWerkz (Now merged with AspectJ) (http://aspectwerkz.codehaus.org/)
- PROSE (http://prose.ethz.ch/)
- The AspectBench Compiler for AspectJ (abc) (http://www.aspectbench.org/)
- Dynaop (http://dynaop.dev.java.net/)
- JBoss AOP (http://www.jboss.org/developers/projects/jboss/aop)
- The Spring Framework (http://www.springframework.org/) as part of its functionality
- The JMangler Project (http://javalab.cs.uni-bonn.de/research/jmangler/index.html)
- Javassist Home Page (http://www.csg.is.titech.ac.jp/~chiba/javassist/)
- Byte Code Engineering Library (http://jakarta.apache.org/bcel/)
- JAsCo (http://ssel.vub.ac.be/jasco/)
- JAML (http://www.ics.uci.edu/~trungcn/jaml/)
- For Javascript:
- AOP Fun with JavaScript (http://www.jroller.com/page/deep/20030701)
- For C/C++:
- AspectC++ (http://www.aspectc.org/)
- XWeaver project (http://www.pnp-software.com/XWeaver/index.html)
- For Python:
- Lightweight Python AOP (http://www.cs.tut.fi/~ask/aspects/aspects.html)
- Logilab's aspect module (http://www.logilab.org/projects/aspects)
- Python/Transwarp AOP Tutorial (http://zope.org/Members/pje/Wikis/TransWarp/AOPTutorial/HomePage) (Replaced by PEAK)
- PEAK (http://peak.telecommunity.com/)
- Pythius (http://pythius.sourceforge.net/)
- For PHP:
- PHPaspect (http://phpaspect.org)
- Aspect-Oriented PHP (http://www.aophp.net/)
- For Perl:
- The Aspect Module (http://search.cpan.org/perldoc?Aspect)
- For Common Lisp:
- AspectL (http://common-lisp.net/project/aspectl/)
- For Cocoa:
- AspectCocoa (http://www.ood.neu.edu/aspectcocoa/)
See also
External links
- Aspect-Oriented Software Development (http://aosd.net/conference) (annual conference about AOP)
- AOSD Wiki (http://aosd.net/wiki) (Wiki specifically devoted to AOP)
- Attempt to explain AOP without buzzwords (http://www.jroller.com/page/colyer/20040531)
- AspectJ (http://eclipse.org/aspectj/) (Java implementation)
- The AspectBench Compiler for AspectJ (http://www.aspectbench.org/) (another Java implementation)
- A detailed series of articles about the basics of aspect-oriented programming and AspectJ (http://www.javaworld.com/javaworld/jw-01-2002/jw-0118-aspect.html)
- Introduction to Aspect Oriented Programming with RemObjects Taco (http://www.codefez.com/Default.aspx?tabid=29&newsType=ArticleView&articleId=98)de:Aspektorientierte Programmierung
fr:Programmation orientée aspect ja:アスペクト指向プログラミング zh:面向侧面的程序设计