Aspect Oriented Examples

Perhaps we could use an easy, canonical example of why someone might need AOP. Here's my attempt:

Three months into a project, the user asks for highly specific logging. For some reason, they want to log instantiation of a bunch of different classes, but these classes are spread out across all sorts of domains. You can't use inheritance, since they all inherit from different objects.

The AOP way to solve this is:

This way, you've solved the problem without abusing inheritance, and without having to change 50 classes by hand.

The canonical examples are pretty compelling (logging, synchronization, billing, security access across class boundaries) but there are any number of possibilities. I realized a need for something like this approximately two years ago when developing a SmartProxy and SmartSkeleton class for a family of servers but didn't have a name for what I was looking for. These classes would handle dynamic failover completely transparently to the calling code. It worked but involved wrapping and maintaining the interfaces over time which became a real pain.

With an aspect, I could have defined before() and after() advice (using AspectJ-speak) that caught and re-routed any failed attempt whatever method was being called, return to the primary server when it was restarted, etc. It would have taken about 20 lines of code compared to 20 lines of code * the number of interfaces * the number of methods in the interfaces. It would move with interface changes over time and support evolution of the advised behavior(perhaps adding rolling back of transactions if no server were available to satisfy the call).

Another example: If you are creating an ASP-based service, you could easily instrument your code to charge certain rates for time spent in value-added code and different rates or nothing at all for time spent in JDK core code. Whatever your billing policy was it could easily change over time with minimal impact.

-- BrianSletten

Let me try to make this a bit more concrete. I have written a text editor which have around 20 "transformations" which the user can apply on the selected text. If no text is selected, it often makes sense to apply the "transformation" to the current character, word or line.

So instead of having each of these transformations start by checking if text is selected, and if not, select the proper unit, I would prefer to put this in as a BEFORE() -- likewise, if text wasn't selected, not text should be selected after the transformation, this however require that some state info can be transferred from my BEFORE() to my AFTER(). Furthermore, the BEFORE()-code somehow needs to know which buffer the transformation is supposed to work on (so that it can select in this buffer). There are other examples where BEFORE()/AFTER()-code becomes useful. For example, normally the run-loop is running, it gets e.g. some input from the user, which results in a method being invoked on my controller -- this may lead to all sorts of nested method invocations, but whatever method is the first, should "merge" the undo stack on exit, so that all the work done, is undone as a single event.

There are many different entries to my controller, so this would require some sort of nesting counter which was incremented in BEFORE() and decremented in AFTER(), and if zero, it would "merge" the new entries on the undo stack.

So all in all I am very hooked on this AOP, but so far I have not figured out if it will ever work in real life (for other than add debug traces to each function or other relatively "simple" stuff, which I can more or less already do by defining "{" to "{ BEFORE();" and "}" to "AFTER;}" :-)

So could something comment on what the expected state of AOP is in e.g. 2010, and if it will ever see its way into existing languages like CeePlusPlus? -- AnonymousDonor

Could someone provide different examples to clarify AOP? I am writing from the perspective of one who knows absolutely nothing about AOP but a little about OO patterns. Having only the above examples, I do not see why AOP is new or advantageous, at least in environments that support inner classes. Consider the SmartProxy example above. Couldn't you do the following (in Java or .NET, anyway)? Then, each time you need something to be wrapped by calls to before() and after(), create an anonymous inner class that subclasses foo's class and overrides foohook(). The override will be wrapped. [There's a little more work to be done to give foo() a general signature, but I think the point stands.]

Thus, the problem of "20 lines of code * the number of interfaces * the number of methods in the interfaces" doesn't motivate me to investigate AOP, since it seems a solvable problem. Perhaps there are subtleties of the deadlock problem, or some other example? -- another AnonymousDonor
This sounds an awful lot decorators (somewhat related to the DecoratorPattern) in PythonLanguage. Short example (not from the RealWorld):

    def makeDec(bar):
        def _decorator(func):
            def _wrapper(*args, **kwargs):
                print "pre", func.__name__, bar, args
                ret = func(bar, *args, **kwargs)
                print "post", func.__name__, bar, args, ret
                return ret
            return _wrapper
        return _decorator

#following is the same as: #def decorated(...): #...code here #decorated = makeDec(42)(decorated)

@makeDec(42) def decorated(a, b): return a * b

print decorated(5) #prints "pre decorated 42 [5]\npost decorated 42 [5] 210"

The way I see it, add metaclasses and/or some other hacks to the mix, and you basically have AOP. -- yet another AnonymousDonor


View edit of November 20, 2014 or FindPage with title or text search