Why Use Aspect-Oriented Technologies?
 HOME  ARTICLES  TECHNICAL LIBRARY  TRAINING

 Articles - Frank


 Articles - Eileen


 Quick Refs


Part I: Why Use Aspect-Oriented Technologies?

Note: I wrote these articles in 2002, and the first AOP conference was in great part a reason why I originally left the IT world in 2003. When I first grasped these concepts, I remember thinking: you've got to be kidding me. It will take a lifetime for the IT industry to wrap their brains around this, and I'm too old to start this now. This is a lifetime of work for the next generation of IT professionals, much less for someone like me. Fast forward to 2007, when my husband's former professor from the Netherlands just happened to be visiting Birmingham, Alabama. We stopped by the university to hear him speak. Granted, he tried to cover days of material in a 1 hour period which is impossible. Nonetheless I was deeply disappointed, but not the least bit surprised, that things hadn't changed all that much in the AOP world. Here is the article I wrote back in 2002, and again, I think many of the things I wrote about then still apply today:

What on earth is AOP, or Aspect Oriented Programming? The curiosity started with Frank noticing that a large number of whitepapers, conferences and tutorials at OOPSLA 2001 were on this subject. The end result of a little investigation so far is that this is the next big wave. OOP is great, but it has some glaring weaknesses that AOP addresses.

"Aspect-oriented software development is a new technology for separation of concerns (SOC) in software development. The techniques of AOSD make it possible to modularize crosscutting aspects of a system."

What does this mean? If you've ever worked on an OO project, you may have run into this: have you ever tried to build a security system? Manage persistence? Do logging? What is the recurring theme about these types of problems?

You may have noticed, for example, that you're unable to just build your system and then "slap" some sort of security mechanism on top of it. Security is integral functionality that touches every part of your system. Likewise with logging, persistence, etc.

In other words, deja vu for an article I wrote previously, it's as if someone took a shotgun to your code. We know what that does to the maintenance burden: makes it cumbersome and error prone. So how does aspect programming solve this? These types of problems are known as crosscutting concerns of a system, and aspects are designed to encapsulate these crosscutting concerns and take them Out of your code. So let's see how this really benefits us by seeing two examples side by side: one without aspects, and one with.

Adding Persistence

Let's say you have a bunch of domain objects with fields and getters/setters, say for an auction system. They might look like this:
public class User {
  private String userName;
  private String password;
  private String firstName;
  private String lastName;
  private String email;
  private Address address;

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  ...etc.
}
At some point, you might realize that maybe these values don't change that much, and do you really want to save values back to the database if they haven't changed? So now you might add something like this to your setters:
						
boolean dirty = false;

  ...

  public String getUserName() {
    return userName;
  }

  public void setUserName(String userName) {
    this.userName = userName;
    dirty = true;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
    dirty = true;
  }
  ...
Elsewhere, you would have code that says:
  if (dirty) {
    // save to database
    dirty = false;
  }
Now, what happens if you decide, fairly late in the game when you have 150 domain objects, that you want to add this into your system? How easy is it to add? Keep in mind that all 150 classes are going to have this same code. What happens when you miss some? Not a pretty prospect, is it?

Using Aspects

How can aspects solve the problem? We'll show the code first, then explain it later:
aspect Persistence {

  Set dirtyObjects = new HashSet();
  // let's assume the action classes are in a package called auction 
  pointcut dirty(DomainObject o):
    target(o) && call(* auction..*.set*(..));

  after(DomainObject o) returning: dirty(o) {
  	dirtyObjects.add(o);
  	// note that the following is over simplified and NOT safe
  	if (dirtyObjects.size() > MAXDIRTY) {
  	   // write dirty objects to database
  	   dirtyObjects.clear();
  	}
  }
}
This special syntax (aka non-Java) means you need a special compiler; AspectJ is one such compiler implementation for Java. From the little testing done so far (Oct 2001) it's not well integrated with Forte, but it is fairly well integrated with JBuilder. Here's a quick run-down on some basic concepts/syntax in this snippet of code, then we'll step through the code.
  • aspect - you must name your aspect. You can loosely treat an aspect like a class (more on this later).
  • join points - places in a runtime cycle where "something happens", or something gets executed. e.g. in Java:
    • method calls
    • method executions (differentiated because of polymorphism)
    • instantiations
    • field references
    • exceptions thrown, etc.
  • pointcut - picks out these join points. Pointcuts and advice (explained further down) have the following parts:
    • target - which instances are you concerned with? e.g. here, we're interested in DomainObject instances
    • && - "and". "Or" is represented with ||
    • call - example of a "designator", i.e. in this case when a method is called
    • * - wildcard, matches return types, method names
    • .. - wildcard for method argument list or different levels of a package structure
  • advice - defines pieces of implementation that execute at particular join points picked out by a pointcut. Different types of advice include:
    • before - this runs just before the execution of actions associated with events in a pointcut
    • after - this runs just after
    • returning - this also runs after, but only if it returns normally.
    • throwing - this also runs after, but only if it throws an exception, e.g.
      after() throwing(Exception e): ...
Now for a walk-through of the salient points:
  Set dirtyObjects = new HashSet();
  // let's assume the action classes are in a package called auction 
  pointcut dirty(DomainObject o):
    target(o) && call(* auction..*.set*(..));
If there are multiple set methods called on a single domain object, we want to be smart and not save the same domain object several times, that's why we stuff dirty objects into a HashSet (it won't store duplicates).

We create a named pointcut called "dirty" (still not entirely sure about the syntax of the parameter yet, e.g. could it also have been done with target(DomainObject)?). We're targeting all setXXX() method calls on all DomainObjects, regardless of return type (the first asterisk), in package auction and any subpackages of auction (the ..*.). Any method that starts with "set", with any parameter list.
  after(DomainObject o) returning: dirty(o) {
  	dirtyObjects.add(o);
  	// note that the following is over simplified and NOT safe
  	if (dirtyObjects.size() > MAXDIRTY) {
  	   // write dirty objects to database
  	   dirtyObjects.clear();
  	}
  }
This advice executes after pointcut event execution, so after the setXXX() methods have executed successfully. We add our domain object to the HashSet so it will eventually be written to the database. The next piece of code is to show if you reach a certain threshold, write to the database and clear out the HashSet. Of course, if you never hit the threshold, this won't work, that's why this is an oversimplified example, but you get the picture.

Tools

One of the issues that comes to mind is: how do you know what aspects are being run, when? Click here for a screenshot of aspects in NetBeans (the picture's a bit large). Look at the navigation pane on the left hand side. It displays the following in a hierarchic fashion:
packages
|-ClassName.java
  |-method()
    |-advisers
How do you know you coded the correct pointcut? Take a look further down:
packages
|-AspectName.java
  |-pointcut
  |-after
  |-afterReturning
and for the adviser, a list of methods that it advises.

It's apparently much cleaner in JDeveloper; there are two panels, and the aspects aren't replicated all over the navigation tree; your Java code is in one tree, the aspects are in another. In the code pane, there are lightning bolts that tag certain methods to let you know there are advisers attached.

Here is an Oct 25th update of working source code, Frank's rough cut.

  Customer.java
  Address.java
  Main.java
  Persistence.java

Applications

There are two types of aspects:
  • Development/testing aspects, e.g. for debugging, logging problems. You'll use these, then throw them away.
  • Production aspects, e.g. security, transactions. You'll keep these.
It turns out there are many types of applications for aspects, some quite ingenious. Some typical problems for which this is ideal:
  • Session tracking
  • Any time you're passing something around all over, just because someone somewhere down the line might need it. e.g. EJB context
  • Frank also suspects this does away with double dispatching and the visitor pattern (I've detested both for years)
When should you use aspects?
  • When you realize you have a crosscutting concern with similar functionality throughout
  • There's a whole discussion on this in a tutorial, will cover later
How are aspects similar to classes?
  • they can be in packages
  • they can be inner classes/aspects (??!!)
  • they can be extended (and implement??)
How are aspects different from classes?
  • you can't instantiate aspects using new, they are instantiated automatically when join points are hit (that's another question, are they really instantiated or is AspectJ more like a precompiler which stuffs code into methods, then compiles them??)
  • by default aspects are singletons...
Other more advanced things you can do with aspects:
  • Aspects can actually add fields to objects, and this gets done at compile time.
  • Aspects can inherit from each other. We're going to see a whole new catalog of design patterns that spring up around AOP.

Implications of AOP

Many of us have chanted the following mantra for years: you can't just design a system, then "slap" security on it as an afterthought, since security touches every aspect of your system. Well guess what? Now you can! So this is going to change the process of software development and peoples' thought processes. This was one area where you previously couldn't take XP to heart, but now you can: don't design it until you need it.

And you can design something when you need it, use it, and throw it away. Without aspects, we need to have some sort of logging framework that we can enable or disable, and the logging code remains and clogs up the system, kind of like cholesterol. With aspects, you simply don't compile in the aspect.

When object-oriented technologies started to hit critical mass, one might have thought that object-oriented databases would supercede relational databases, but they haven't. Relational databases are ubiquitous in our industry. Why? It's because SQL is a simple but powerful language. Aspects remind me of the "select" and "update" commands, only instead of selecting and updating data, you're selecting and updating objects, methods, etc. It's as if we've finally begun to meld the best of the object and relational worlds.

Past, Present, Future

Initial research shows the concept of AOP first popped up around 1995 in OOPSLA circles. Frank remembers now that the University of Twente in Holland, where he studied, had something called composite filtering in Smalltalk (which is what aspect programming is, only it wasn't called aspect programming then. It was also done by a small niche. Many of the ideas seemed to be pioneered from here; in fact, the next Aspect conference is at the University of Twente in April 2002). Apparently at OOPSLA, beta versions of the language didn't do very much; however, since then the language has evolved drastically,to the point where we can now see the obvious benefits. On the AspectJ site, they say that user feedback is driving the language design, and you can contribute to this effort through:
  • users@aspectj.org
  • support@aspectj.org
For those few who've seen Frank give some simple demos, the consistent reaction has been excitement and immediate realization that a lot of things can be cleaned up and collapsed. They suspect in 6 months to a year we'll all be doing AOP.

References

  AOSD.net - Aspect Oriented Software Development
  AspectJ - lots of tutorials, and a compiler implementation for Java
  AspectJ FAQ
  AspectJ Programming Guide


spacer
Last updated:  Wednesday Apr 09, 2008 @ 06:53 AM