Aspect-Oriented Programming (AOP)

One of the primary evolutions in software engineering is the separation and encapsulation of concerns. This has been progressed from machine language to imperative languages with procedures/methods. After that we’ve seen the progression from imperative languages to object-oriented languages. In object-oriented languages new ‘levels of encapsulation’ are introduced: classes and packages. Nowadays we see the upcoming thinking in components. But unless all this techniques we still have concerns defying these forms of encapsulation. We call them crosscutting concerns, because they cut across many modules in a program. Logging is the most used example of such a concern. Logging affects every logged part of the system and thereby crosscuts all logged classes and methods. So we still have redundant code in our programs. How can we solve that?

Gregor Kiczales and his team at Xerox PARC originated the concept of Aspect-Oriented Programming (AOP)


as a solution for this problem[1]. This team also developed the first and most popular AOP language, AspectJ.

AOP

AOP introduces a solution for crosscutting concerns in software programs. In AOP you can use some crosscutting expressions that encapsulate the concern in one place. This place is called the ‘Aspect’. Or in other words: aspects are well-modularized crosscutting concerns. Such an aspect consist of several elements: the pointcut, join points en the advice[2].

A pointcut is a set of join points. A join point is a point in the flow of a program. If one of the described join points in the pointcut is reached, the advice will be executed. The advice is a piece of code associated with the pointcut. In this way we can avoid crosscutting concerns.

I already mentioned the example of logging. Without aspects we have to give each method we want to log a line calling a log method. This must be done in every module we have. With aspects we can just define a pointcut with the needed join points (by example before or after the methods we want to log are called). In the advice we program the log method. In this way we avoid a lot of redundant code!

AspectJ

One of the most used AOP languages is AspectJ. AspectJ is an aspect-oriented extension to the Java programming language[3]. AspectJ enables you to use the above clarified principles in Java. So you can use aspects with a pointcut and an advice. You can also add an inter-type declaration to an aspect. An inter-type declaration allows you to add methods, fields, or interfaces to existing classes from within the aspect. We want to clarify this all a bit with an example of an aspect in AspectJ.

In the piece of code[3] below you se the definition of an pointcut in AspectJ. This pointcut, move(), defines on which join points this aspect has to react. In this case the keyword call is used, this means that if the specified method is called, the advice defined for this pointcut will be executed.

pointcut move():

call(void FigureElement.setXY(int,int)) ||
call(void Point.setX(int)) ||
call(void Point.setY(int)) ||
call(void Line.setP1(Point)) ||
call(void Line.setP2(Point));

The advice is defined as seen in the following piece of code. Here we define that before (before()) each join point defined in pointcut move() we print the line “about to move”.

before(): move()
{

System.out.println(“about to move”);

}

To show the possibilities you have we want to show you one last example. In the piece of code below you see that we also define an after() advice for the move() pointcut. This means that after each join point defined in move() the line “just successfully moved” is printed.

after() returning: move()
{

System.out.println(“just successfully moved”);

}

You also see an extra keyword: returning. This means that we only execute this advice if we successfully return from the called method. So if an exception has been thrown this advice is not executed. We can react on exception with use of the keyword ‘throwing’ instead of ‘returning’.

Of course a lot of other possibilities exist. We only showed you a brief overview with the main idea behind aspect-oriented programming.

Example

I want to show you a bigger example of the use of AOP because I like the idea behind. AOP can really make your code more modular. On the web you can find examples of AOP used for logging and security checks. AOP can also give you support for using design by contract in programming languages which doesn’t support that (link). The last example I want to mention is using AOP for testing (link).

The example I want to show is using AOP for replacing the Visitor pattern (Gang of Four). In the diagram below you see a structure implementing the Composite pattern.

Composite structure

Adding functions to this structure can be done by using the Visitor pattern. The Visitor tree than looks as seen in the figure below. You see to visitors: PricingVisitor and ColorVisitor. The PricingVisitors implements a function calculating the total price of a component including the price of its subcomponents. The ColorVisitor implements a function checking whether all subcomponents has all the same colour as a particular component.

Visitor tree

By now I do this implementation by using two aspects: Pricing and ColorChecking. The Pricing aspect makes use of the already existing getPrice method in each Component. Each Component has an attribute price, which can be set. In the Pricing aspect we change the behaviour of the getPrice method in such a way that it also add the price of the subcomponents. For doing this we first have to define a pointcut:

public pointcut price(Composite c): target(c) && call(int getPrice());

Because only Composite objects has subcomponents we limit this pointcut to Composite classes by target(c). I can use c because I have parameterized our pointcut by adding Composite c to it. This is useful because I now can use the instance c in the advice. I limit this pointcut also to the method getPrice ( call(int getPrice()) ). In summary: this pointcut defines all method calls to Composite.getPrice() as join points.

Now I can implement the advice. Because I want to show you as much possibilities as possible I’ve chosen to implement this by only changing the behaviour of the existing method getPrice, instead of introducing a new method (we will use an inter-type declaration in the ColorChecking aspect).

/**
* Calculate price of subcomponents and add this to the price of this component
*/
before(Composite c): price(c)
{

System.out.println(“price called on COMPOSITE: “+c.getClass());
p = c.price;
int i = 0;
for(int index = 0; index < c.getChildCount(); index++)
{

System.out.println(“price called on sub component: “+c.get(index).getClass());
i += c.get(index).getPrice();

}
c.setPrice(p+i);

}

In the code above you see the first advice I used. The keyword ‘before’ defines that this advice will be executed before the pointcut price(c). As you can see in the code, we calculate the total price of all the subcomponents and add this to the price of this component (c). But, before we change everything we save the current price in variable p (p = c.price).

After the pointcut the next code will be executed:

/**
* Set price back to price of this component
* If we don’t do this, the next time the subcomponents will be
calculated double, and so on
*/
after(Composite c) returning(): price(c)
{

c.setPrice(p);

}

You see that I now use the keyword ‘after … returning’, this means, as already explained above, that after a successful return we execute the code ‘c.setPrice(p)’. So the ‘old’ price, the price without the subcomponents, is set back. This is necessary because otherwise we do not know the price of this component anymore. If anything changes in the price of this component or its subcomponents we can’t calculate the total price anymore, because we only now the total price, and not the price of this component itself.

The second aspect I have implemented is the ColorChecking aspect. We now use an inter-type declaration. This is needed because not every Component has a Color attribute. We introduce an isColorAllTheSame() function in every Component. This method returns true if all the colors of all subcomponents are the same as the color of this Component itself. But, because not every Component has an attribute color and a method getColor, we have to check this first with use of the reflection possibilities in Java.

public boolean Component.isColorAllTheSame()
{

boolean boolResult = true;

//do this Component have a getColor function?
Color thisColor = null;
Class thisClass = this.getClass();
System.out.println(thisClass+”.isColorAllTheSame: checking…”);
try
{

Method m = thisClass.getMethod(“getColor”, new Class[]{});
Object result = m.invoke(this, new Object[]{});
thisColor = (Color) result;

First, as shown above, I check whether this component has a color or not. If so I set the variable thisColor, otherwise this variable will stay null. We of course catch all sufficient exceptions which can occur in this situation. After that I have to check the color of each subcomponent.

//check colors of subcomponents
for(int index = 0; index < this.getChildCount(); index++)
{

try
{

//try getColor function
Component c = this.get(index);
Class cl = c.getClass();
Method m = cl.getMethod(“getColor”, new Class[]{});
Object result = m.invoke(c, new Object[]{});
Color color = (Color) result;

//check if subsubComponents have all the same color
if (c.isColorAllTheSame())
{

//if we have a color, compare it with the subcomponents color
if (!((thisColor != null) && (thisColor == color))
{

boolResult = false;

}
else
{

boolResult = false;
break;

}

We, again, have to check whether the subcomponent has a getColor method or not. If so I compare this color with our color. Otherwise I only have to call the isColorAllTheSame() method of this subcomponent.

In this way each Component now has the isColorAllTheSame method. We can use this method everywhere we want (one little note: in Eclipse you have to open code using a method introduced by an aspect in an AspectJ editor, instead of the normal Java editor). Otherwise the editor will give errors, because the function isn’t known.

Conclusion

After all, Aspect-Oriented Programming is a nice methodology filling the gaps of Object-Oriented Programming. Before I looked at the possibilities of AOP I was a bit negative about it. In a quick view I thought it was only making your code less readable and maintainable, because of adding Aspects wherever you want. But used in a good way, AOP can replace your crosscutting concerns with well-modularized code. And that, in principle, is what we want: well-modularized, non-redundant code!

[1] Kiczales, Gregor; John Lamping, Anurag Mendhekar, Chris Maeda, Cristina Lopes, Jean-Marc Loingtier, and John Irwin (1997). “Aspect-Oriented Programming”, Proceedings of the European Conference on Object-Oriented Programming, vol.1241, pp.220–242.

[2] Aspect-Oriented Programming, Wikipedia – the free encyclopaedia http://en.wikipedia.org/wiki/Aspect-oriented_programming

[3] The AspectJ Project, http://www.eclipse.org/aspectj/

2 Comments Added

Join Discussion
  1. viakos April 10, 2007 | Reply

    great script. !!! it’s making code less readable and maintainable

  2. Johan den Haan April 10, 2007 | Reply

    Viakos,
    It depends on how you view it. The visitor pattern is a well-known Java pattern proposed by the Gang-of-Four. The only thing I do is implementing it with help of AspectJ. I agree with you that man should use it with reservations, but I like separation between model and functionality, especially when using the model in many different contexts.

Leave a Reply to Johan den Haan Cancel reply