Aspect-oriented Programming demystified

Date:   Saturday , December 08, 2007

Aspect-oriented programming (AOP) has recently become quite a hot topic. The name, which sounds similar to object-oriented programming (OOP), may convey the impression that AOP is an alternative to OOP. But despite the similarity in name, AOP is not expected to replace OOP and in most cases it supplements an OO programming language and provides the architect with techniques to come up with elegant solutions to some of the programming challenges not easily handled through object-orientation. This article will explain the basic AOP concepts and touch upon the advantages and limitations of using AOP.

In the ever-changing technology world, designing an application, which is both maintainable and extendable, is always a big challenge. In the process of creating the architecture for such an application, an architect considers not only the present requirement but also has to take into account possible future requirements. However, it is not possible to predict the future. An unforeseen requirement can lead to a significant change and re-implementation of many parts of the system. The alternative of focusing too much on low-probability requirements can lead to a confusing and bloated application. For example, if the current system does not require logging, should the architect include a logging mechanism in a system?

Therefore, the system architect always faces the dilemma of whether to leave out the feature and under-design or to consider it and over-design. The question of how much design is too much needs to be answered. The task of the architect of a reusable library is even more difficult because it is harder to imagine all the usage scenarios for the library. In a real life situation, there will always be requirements, which have not been foreseen at the time of initial design. Some of the changes may be non-functional in nature and may cut across many programs. The need to optimize performance can also add to the problem. A design would have been made initially to address a single function, but over a period of time it tends to lose its purity. Additional functionalities are added to the object. In AOP terms, the problem is known as ‘mixing of concern’ and AOP is designed to avoid this problem. It addresses these issues and solves them in a more elegant way.

This mixing of concerns leads to a condition called ‘code scattering’ and ‘code tangling’. With code scattering, the code necessary to fulfill one concern is spread over the classes, which are designed to fulfill another concern. Code tangling involves using a single method or class to implement multiple concerns. Both of these problems break the fundamentals of OO and cause headaches for designers. A developer doesn’t have to be in the industry long to find out the effects of tangled and scattered codes that include classes that are difficult to change, codes that can’t be reused, and codes that are impossible to trace.

Like many innovations in the field of IT, the origin of AOP also goes back to Xerox PARC. Gregor Kiczales and his team originated the concept of AOP in 1996. His team also developed the first and most popular general-purpose AOP language, AspectJ, which was an extension of Java. Then it was a new approach for designing programs. It was also a set of guidelines to make more readable and reusable code.

The basic principle of object-oriented programming is to group functionality into classes and create relationships between these classes. However, in practice it is not always possible to group a single functionality into one class and the functionality may be spread over more than one class. In AOP terms, such functionality is referred to as ‘aspects’ or ‘concerns’. In a credit card processing system the primary functional requirement would be to process payments, which is the ‘core concern’. However, there will be other non-functional requirements like logging, transaction integrity, authentication, security, performance, and so on, and these are ‘crosscutting concerns’.

Any application will have several core and crosscutting concerns. Using current programming methodologies, crosscutting concerns span over multiple classes, resulting in systems that are harder to design, understand, implement, and evolve. In AOP, aspects are coded separately from the classes, which need to have it. It is the task of the compiler to merge the aspects into the classes. This process of merging core and crosscutting concern is called ‘weaving’. The weaving can happen at the source code level or at the byte code level. The weaving can also take place at runtime. This process is somewhat similar to firing of database triggers.

For a compiler to weave crosscutting concerns with the core concern, three things need to be specified viz what (= ‘advice’), where (= ‘join point’), and how (= ‘point cut’). Advice code can be plugged into main code at places like ‘method calls’, ‘field access’, and ‘exception handling’ and these points are ‘join points’. Point cut is the glue, which tells how an advice is to be linked to a join point. It is possible to specify where the advice code will execute i.e., before, around, or after the join point match. The method of specifying this differs widely from one AOP implementation to another. It can be via an XML configuration file or metadata within code. Using regular expressions to identify join points is most popular. For example, “*” will match every class loaded by the JVM and invoke the aspect and “mypackge*” will match all classes in mypackage.
Many implementations of AOP are now available. AspectJ was the first implementation. Other popular implementations are JBoss and Spring. All of them have reached a level of stability, are quiet usable, and can be used with most popular application servers. Microsoft .Net framework also supports AOP.

AOP is very powerful and easy to use, but the ease with which these changes can be implemented and the way in which code execution can be modified outside the code itself can lead to unintended consequences affecting all parts of the application. A logical mistake made by a programmer in expressing a crosscutting concern can lead to widespread program failure.

Programmers need to be able to read code and understand flow to prevent errors. With AOP they need to become familiar with the idea of an aspect injecting code to alter the behavior of their code. Understanding such code can be difficult and requires a proper visualization tool. Such visualization tools have not yet matured.

AOP makes it very easy to inject code into an application. This has significant implications on application security, which needs to be properly understood. The potential for creating malware also exists.

In spite of these limitations the advantages of AOP make it a worthwhile technique to try out. The use of AOP results in modularized implementations and can have the following advantages:

* System with less duplicated code
* Reduced code clutter
* More understandable and maintainable code
* Easy to add newer functionalities by creating new aspects
* Delay making design decisions for future requirements