|  |
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

|  |
|