Aspect-Oriented Programming with AspectJ
He has divided the book into four parts. Part I provides a brief sketch of AOP and introduces its concepts. AOP builds on OOP, asserting that we need a new programming entity called, wait for it, an aspect. Mr Kiselev's explanation of aspects reminded me of that bit in The Hitchhiker's Guide to the Galaxy when the planet Golgafrincham divided its population into A types (who were the leaders, the scientists and the great artists), the C types (who were the people who did all the actual making of things and doing of things), and the B types, who comprised everybody left over: telephone sanitizers, advertising account executives and hairdressers. As I understand Mr Kiselev, the AOP view of things is that objects and classes (A type thinkers) and low-level procedures and APIs (C type doers) can be nicely encapsulated using traditional components. But aspects, software's little hairdressers, get their fingers into everything, and until now there has been no way to encapsulate them. This of course is what AOP in general and specifically the AspectJ superset of the Java language set out to do.
AspectJ's eponymous aspects are constructs not unlike ordinary classes. Mr Kiselev has not resisted the temptation to make an aspect Hello World example, and it looks reassuringly so-whatish:
package intro;
import java.io.*;
public aspect HelloWorldA
{
public static void main(String args[])
{
System.out.println(Hello, world!);
}
}
Mr Kiselev then lays out his stall of New Things. A join point is any point in execution flow that AspectJ can identify and -- to get slightly ahead of ourselves -- execute some extra code. The most frequently used kind of join point being the call to a method. Pointcuts specify collections of join points; as a regular expression is to an instance of matched text, so a pointcut is to a matching join point. An advice (with horrid plural 'advices') is the code to be executed when a given pointcut is matched. If you are familiar with Eiffel's pre- and post-conditions, then you'll understand if I say that it is common for advices to run in the same way, topping and/or tailing the execution of a method. The differences are that aspects are specified from outside the method without touching the method or its class's code, and that aspects can be applied to multiple methods in one go. Mr Kiselev concludes this section of the book with a few simplistic examples of 'here is class A, here is class B' kind.
In Part II Mr Kiselev rolls up his sleeves and takes us through an extended, realistic example. I did wonder if perhaps it weren't a wee bit too realistic, as it is a miniature website application for news story submission and reading -- sort of Slashdot Ultralite -- all done using JSP and a MySQL database. Just explaining this setup, without even using any AspectJ, consumes a 15-page chapter. Since I am a C++ programmer who has not had any contact with JSP, I was initially anxious that I might not be able to follow this. However, recalling that www.[name withheld].com, the clumsiest, ugliest corporate website on the Internet, is programmed in JSP, I reasoned that if the dolts that programmed that site could understand JSP then it couldn't be very hard. So it proved.
The first example comprises adding password protection to the application. This is achieved by adding an advice that intercepts calls to doStartTag() methods. The advice can test if the user is logged in and, if he isn't, throw an exception that will dump him back at the login page. (Who says exceptions aren't 21st century gotos?) At this point Mr Kiselev admits that the cute 10-line implementation that he initially shows is in reality a non-starter; for one thing not all pages that must be secured define doStartTag() methods, for another the aspect can't reach an instance variable it needs to read because it is declared in protected scope. The second problem is easily overcome. AOP offers a mechanism by which extra classes can be bodged ('introduced' is the preferred verb in the AOP community) into the hierarchy as parents of existing classes. He uses this to add an accessor method for the field in question. The other problem is not so neatly smothered, and it is somewhat ruefully that Mr Kiselev produces his final, two-page solution. But I think that it is greatly to Mr K's credit that he does this - it tastes like programming in the real world as I have experienced it.
For the rest of Part II, Mr K demonstrates other applications of AOP using the AspectNews code. This includes Eiffelish design-by-contract stuff, improved exception handling, various debugging and tuning techniques (specifically logging, tracing and profiling) and a chapter on runtime improvements - stream buffering, database connection pooling and result caching - which show the AOP way to do things, usually where I would expect to be putting in proxy classes.
In part III we get down and dirty with the AspectJ language. This is the part where the book explains the obscure stuff: how to make a pointcut that picks up object preinitialization, or make an advice that goes off only when you are exiting a method on the back of an exception. I skimmed this bit - I guess it will become vital when I start using AspectJ in earnest. It looked good and clear on a flick through. A brief part IV contains some patterns, to give one a start when engaging AspectJ in earnest. Apparently it is horribly easy to create infinitely recursive situations, so if you here a faint popping sound from your machine it will be the stack colliding with the heap. There are seven appendices, supplying such things as a summary of the API in AspectJ's packages and hints on obtaining and using the Open Source supplementary tools mentioned in the book (Tomcat JSP container, MySQL database and Ant make replacement). AspectJ itself, now escaped from Xerox PARC, can be downloaded from the Eclipse website.
Complaints? None really. Oh all right, here's a nitpicklette because it's you: at page 75 Mr Kiselev adopts the irritating Internet habit of writing 'loosing' when he means 'losing'. Note to publisher SAMS proofreaders: do I win 25 cents?
For the rest, this is a lucid and readable book that describes the Next Big Methodology. I'm a bit alarmed at the prospect of squeezing new actions into the cracks of existing code, but I dare say I'll grow to love it.
A word of warning to the eager: since this technology is currently implemented as a species of preprocessor that relies on having all the source code available at once, so it is rather slow and probably isn't going into production shops for a while. There again, I seem to remember the comparable Cfront C++ compiler doing rather well, before we had platform-native C++ compilers.
And to the sceptics: if you think you can ignore AOP, don't forget the fate of the A and C type inhabitants of Golgafrincham, who having sent their B type telephone sanitizers into exile were all wiped out by a germ caught from a particularly dirty telephone.
You can purchase Aspect-Oriented Programming with AspectJ from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
What is Aspect-Oriented Programming?? I've never heard of it!
Microsoft-oriented development book at Microsoft Press!
This book contains every programming concepts and practices to avoid like hell!
I love that aspects seems to provide alternative techniques without loosing any ease-of-use, coing-wise. I was afraid that in switching to this new method I'd loose some functionality, or maybe loose some speed, but so far so good. Nothing to loose any sleep over. :)P
You are not the customer.
I should have stuck with Lisp all this time. When OO became hot, we could switch to OO without a preprocessor (early C++) or a whole new language (C++ or Java). (Eventually, Lisp got CLOS -- the first standard language to do OO, in fact.) If AOP gets hot, that'll just be a few more macros.
Once you've used a language like Lisp with closures, macros (at the language level, not wimpy C macros), and code-is-data, it's hard to go back. I feel sorry for everybody who has to use Java, for whatever reason, and will have to get a new language/compiler/libraries just to take advantage of a slight change in "what's hot today".
System.out.println(Hello, world!);
Where are the quotes?
I dont trust this guy if he cant write a HelloWorld app.
Sounds a lot like adding a pre "exception" handler in c++, mixed with somewhat normal exception handling, and doing a Microsoft and making it declarative. Sounds like an interesting feature, but without reading the book and seeing what else there is, hardly anything earth shattering. Just another way to have the compiler/dev environment formalize a programming practice.
A methodology hasn't made really made it until somebody has published a Proper Book
Are they kidding. Hell there probably books out here on clipping your finger nails using a new methodology. Now days having a book don't mean squat (unless you're a tree, beaver, or a bird).
AOP would seem to let you over-ride methods or invoke special handling *without* touching the object directly. You simply tell the compiler "When this method is called, do this first (or afterwards)."
On the one hand, this could lead to spagetti code nightmares, since execution paths could become effectively untraceable. On the other, it's in many ways cleaner than putting your special-case or over-ride code directly into the methods and objects directly.
--Dave
Writing to a log before and after an event is an aspect. A logging facility could be coded as an aspect.
D
Listen, strange women lying in ponds distributing swords is no basis for a system of government
The common examples seem to be persistance, concurrency, and something else. AOP is OK, my problem though is that its applicability to orthogonal issues seems (to me) limited. I am rarely able to find any more uses than the common three examples. I am much more interested in some of the recent work done on Traits Programming.
One man's pink plane is another man's blue plane.
'Advice' in Emacs Lisp is handy for running your own custom code before or after any existing function. So it's another way of adding hooks to existing code. A highly customizable app like Emacs is a natural place for this sort of language facility.
And of course, INTERCAL has the 'COME FROM' statement.
-- Ed Avis ed@membled.com
Aspects are cross-cutting concerns, they are things that cut through numbers of classes. My way of thinking: draw vertical rectangles side-by-side and call these "classes", now draw a horizontal box that cuts through them all and this is an "aspect".
The simple example, and one used in the book I believe, is that of logging. Say you have to log the entry to and exit from every single method in your code. Typically you would probably write this directly putting "entering XYZ, exitting XYZ" actually in the code. But with aspects you can write one aspect that basically says "on entry to any method log the method and parameters, on exit log the method" and compile your code and away you go.
So? Why would I want to do this? Well, now that you have been through your development process and discovered everything runs fine, you decide to go into production. Want to remove every single log line to improve speed? With the "normal" approach you'll have to write a script to remove them or do it manually. With aspects: just dont use the aspect in the compilation! Put them back in by compiling in the aspect again.
For me aspects are a real benefit but they do you head in for a while when you're an OO programmer!
Aspect oriented programming is moderately useful, though, if it isn't built into the language (and, in java, it isn't) it can be cumbersome to work with.
In java you can get 50% of the way to AOP using Dynamic Proxies (see java.lang.reflect.Proxy) which allows you to wrap all method invocations or an object. This without an outside tool. This is how a lot of j2ee app servers do thier magic.
By and large, the more I work in java, and the more I work in Lisp, I realize how lacking java is in dynamic behaviors. The lisp guys yawned when OO became all the rage because, well, it is so easy to do in lisp. If AOP gets big in java, they will yawn at that too:
"Oh, so functions and try blocks are your boundry block for inserting aspect oriented code? Well, *every parenthisis* is ours. Put that in your JVM and smoke it."
Cheers,
prat
The sad thing is that the loggin facility is the only convincing example I have heard so far. :P
"Agree with them now, it will save so much time."
One example of Aspect Oriented Programming for compiler writers:
t ml t tp://www.southern-storm.com.au/treecc_doc/treecc _1.html#SEC1
1 ,00.asp
http://www.southern-storm.com.au/treecc_essay.h
http://www.southern-storm.com.au/treecc.html
h
It is also rumored that Portable.NET will use treecc for the creation of a JIT engine sometime in the future.
From my limited understanding, Aspect Oriented Programming combines the power of the Visitor and Inheritance patterns without the drawbacks of either.
Another interesting link:
http://www.pcmag.com/article2/0,4149,44061
The other is probably design by contract or something like that. Checking that things that call a method pass good parameters and that methods return what they say they should. A generic aspect could check that all parameters are not null and that a method doesn't return null. A more specific aspect could check particular method parameters, return values, and object consistency. Once confirmed to be working you remove the aspects and your code will "just work like normal" *gulp*
I'm not trying to troll here, but I'm afraid this might sound like it.... It sounds to me like the main selling points of AOP are that you don't have to design things well in the first place, because if you missed something, well then you can change how your objects behave without redesigning them.
The place where this wouldn't be true is with code that's part of the API or other code that comes packaged. I think that changing the behavior of this type of code sounds pretty dangerous to me - there's a reason that some data is kept in private and protected variables! Wouldn't you get into situations where you've added and aspect or a parent or some such thing, and in the process you access a private variable, and then you upgrade your runtime environment which changes the INTERNAL structure of the code that you hooked into (leaving the external API the same), breaking your code? Isn't that what code encapsulation is for? What I'm hearing touted as AOP's best feature is that you can break encapsulation.... Count me out.
It looks like the concept is to group common methods from many different classes into a form that can be acted on uniformly. The example they gave allows for the creation of several multi-layer classes, all related and built upon each other. A "join point" is constructed as a collection of all methods that actually create new objects. The article explained that this is particularly useful for security, since while there may be many different classes that can be created, a join point can be used to allow or disallow the creation of any or all of them in a single place. The advantage is that security code does not have to be maintained in each class independantly.
Yup. Nothing can save it from slashdot.
Since AspectJ is getting some attention I figured i would point out some other AOP resources
How about blocks in Java, or functors in the Jakarta Commons Sandbox?
Yeah, this review didn't introduce AOP that well.
g i/~checkout~/aspectj-home/doc/progguide/index.html
Going here:
http://dev.eclipse.org/viewcvs/indextech.c
I found this code example:
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));
and then this:
after(): move() {
System.out.println("A figure element moved.");
}
As you can see, "after" any method call as defined by the pointcut, System.out.println is executed to reflect this fact.
I can see how this would be great for logging, checking pre/post conditions, quicker debugging, or anything else that is of a "horizontal" nature in your code.
The original article that introduced it can be found here (download links for the article in several formats are at the top). Google also has a nice collection of links.
Donate free food here
I did a paper on AOP last semester. Basically, AOP not only gives you an object-oriented view of the code, but also splits it up according to other aspects of its functionality, like "security", or "debugging". Then, when you want to add a certain functionality to multiple objects, all you do is name all of the class methods that are affected (called a "joinpoint"), and then write one section of code, instead of changing each and every object (or class) that you would have to do if you were using an OO language. Go to http://www.parc.com/groups/csl/projects/aspectj/in dex.html and look at some of the PPT presentations. They describe it pretty well.
AOP is a very interesting notion in that it allows you to separate your concerns. Application logic, security, logging, transaction maintenance, etc, etc, etc. All of these things can be written separately but are then woven together at specific critical points. The result of good AOP programming is that your code is cleaner, and the guy writing application logic thinks only about application logic, not about persistence, caching, security, etc, which are all implemented as separate conerns and woven together later.
The real power is the ability to define this at runtime instead of compile-time, though. Imagine this- you write a generic caching and persistence layer for an application. You write this once. Then, at runtime, any time you want to apply this persistence layer's functions to an object, you just instruct the application (through a config file or some other means) to weave the persistence layer in with a specific object. Boom. Instant persistence. You could do this with any feature really, as long as you wrote each aspect generically.
This is a pretty extreme boon for certain classes of applications. Specifically, take any application that's modular or componentized. Each component can now have additional services dynamically bound to it. You can apply code as a policy over any activity...field modifications, method calls, constructors...etc. As a result, you can apply special policies to modules or compnents in your application without having to actually code them in to the component.
Other possiblities include applying advice to the constructor of Thread objects that checks threads into a registry on their creation. Now, every thread in the VM has a handle in this registry. If a thread flies off into an infinite loop, you can see the stacktraces of all the threads easily and have a better point to investigate from.
It's worth noting that the applications that really will benefit from this methodology...applications servers...are taking note of it. The JBoss 3.x series was written with a limited form of AOP that can only apply policies in limited ways to objects that implement certain interfaces. The next major version of JBoss promises the opportunity to leverage runtime AOP so that any Java object can have server services bound to it regardless of whether it implements an EJB interface or not.
Again, though, the power comes in in the ability to make these pointcuts at runtime. AspectJ, as far as I know, still doesn't offer this, so you can't dynamically change the aspect policies in your application dynamically. That makes AspectJ pretty useless for AOP in my book.
Then again...I could be talking arse. Here come the flames!
The advantage is that security code does not have to be maintained in each class independantly
This is precisely what I use AOP for. Whilst there is tremendous opportunity for spaghetti coding, so long as you adhere to some reasonable standard of layout and documentation it works out much more maintainable for certain design patterns.
It's not that I'm Anti-American - I'm Pro-Freedom
Seems in a large project it would be real easy to forget about code that executes that you cant see.
The nice thing, then, would be a smart editor which is aware of aspects, and can draw flags on top of the source code you're reading so that the programmer is warned that an Aspect will be sticking it's nose in.
Even better, you could click those flags to apparently expand the aspect's code inline, revealing exactly what statements will execute when the function runs. Of course, this can't be reliably done in all cases, if the Aspects are something that can be toggled on/off as the program runs.
In that case, the editor might have to be pessimistic, and assume "an Aspect might apply here...". But that might not work well either. In the end, you need smart programmers, both writing the aspects, and using them.
When will people realise that the most important thing in a programming language is to make it possible to reason about one part of it independent of another part? Most of the time spent developing a program is spent modifying code, not creating new code!
Unfortunately people don't realise this: they just want a way of hacking something existing into something different, cross their fingers and hope that it works when someone changes some other part of the system.
Sadly, it's not just AOP: some of the "usual" OO programming language features suffer this kind of problem too.
Then again, maybe I'm completely wrong, and AOP has a sound theoretical basis and has been created by someone with deep understanding of programming language developments over the last thirty years... someone please reassure me!
The Software Practices Lab at UBC has been doing all sorts of AOP research lately. Of particular interest:
They're also working on AspectC and AspectSmalltalk. It's my understanding that UBC is one of the major world centers in AOP research -- do you think I should do a PhD there?
Anybody who has worked extensively in Java has found this problem before. Cross-cutting concerns - you know, those systemic things that infiltrate their way into every module of your humongo-system, no matter how you try to partition it. Now, object-oriented programming, isn't that supposed to let you "blackbox" things so you can just abstract away such things and throw them in some "common" or "system" package and be done with it? Sure, you can. And you probably have. And I've done it too.
But these solutions can be suboptimal - for example, a project I once worked on had an Interface in the com.blah.blah.system package for logging, messaging, persistence, and some other features. These were always nasty pains in the ass to manage. I mean, some implementor of these objects existed everywhere in the system - if something changed fundamentally, or there was some insuffiency in the interface that was discovered, god forbid, you'd have to root around for hours changing code everywhere. Especially when exception signatures changed. Which eventually leads, in sheer frustration, to using Runtime exceptions everywhere, or declaring all of your "system" interfaces with "throws Exception". Ugh. Each solution seems worse than the problem.
Admittedly, problems like this can be solved with good refactoring tools and practices. But not always well. The exception issue for "system" or "cross-cutting" interfaces was one I've never seen solved well (again, I'm thinking of Java here, it's the language I have the most experience working in large commercial-scale projects in where this stuff is really important). If you are working on medium or small sized open source projects, or medium or small sized tools or desktop applications, you may never have come across these kinds of limitations or frustrations in sufficient numbers to justify looking into AspectJ/AOSD in general. But if you've worked on large enterprise software projects, I'm sure you can see that there is a need to "patch," but certainly not replace, the standard OOP methodology to address these kinds of concerns.
This sounds similar to the Common Lisp Object System (CLOS) :before and :after methods.
If I remember correctly, in CLOS you can specify a method "foo", and then another method "foo" with the ":before" modifier that would be executed before the normal "foo" method. There is also an ":after" specifier.
In a band? Use WheresTheGig for free.
Want to remove every single log line to improve speed? With the "normal" approach you'll have to write a script to remove them or do it manually.
.h file, re-compile and you're golden. That removes all the #ifdef debug code you put in when you were writing it.
Or you change one #define in one
Do they teach programmers anything useful these days? Sheesh.
Lemon curry?
Instead of looking for radically new approaches in computer language development why doesn't someone introduce more colour into standard C. For instance we have if and while, how about adding verbs such as when, where or how.
Taking it further we might like to introduce more polite language into code such WouldYouBeSoKindAsTo or WhenYouAreReady. Imagine the code you could write...
when (time == "morning")
WouldYouBeSoKindAsTo (turn_on_alarm);
Alternatively we could convert C from English into, say, German. So if would become wenn etc. You could even mix nationalities. For instance if you wanted to be very forceful about a particular if statement you could use the German. If you wanted to seduce the code you might use the French.
Come on all it takes is some imagination. (Alternatively we could all just start using befunge!)
-- "Can't sleep, clowns will eat me!"
I'd have to disagree that it won't be used in production shops any time soon. It's really a matter of the word getting out, which undoubtedly will be helped by both the book and the appearance of this review on /.
A team I was on early last year had a legacy Java db access module that was rife with poor exception handling. We wrote a single aspect that joined on all exceptions, trapping only JDBC exceptions, and had the aspect trap the SQL error code, the ISAM error code, the offending method and source code line. After recompiling the module with the aspect included, we popped the new JAR into production and used the trace files to find the offending code. Altogether it took 2 days to address the errors. So we re-recompiled the JAR, this time with the aspect removed, into production it went, and received a few beers for our "inventiveness."
Honestly, this is one of the most useful Java tools I've ever run across. I guess I should have sent the PARC guys money for some tallboys.
is not really a real person but is one of the funniest tech writers out there. She is famous for the history of the microcomputer, and is widely and deeply revered by everybody who's read her
She also did a parody of our own Slashdot, which is absolutely f*cking hilarious.
I strongly recommend anyone who hasn't read any stob to go and check out the archives and then laugh yourself stupid for half an hour.
Build your own website - full service homepage system your m
But. . .
This has the feel to it that the programing methodology is becoming religious dogma, rather than a useful tool.
I've been getting that feel for a while now, as OOP languages start to compete on their "purity" or whether they're "real" OOP languages or not.
I've been programing "Object Oriented" since the 70's. In languages, like APL, that no one would consider "Object Oriented." Object Orientation is an abstract concept in itself that allows us to more easily abstract real world items into virtual objects and to manipulate them in a virtual world.
That's all. It is occasionally a very useful tool to have in one's bag of tricks. Sometimes it really doesn't apply at all and trying to force a fit just makes things labored and crude.
Trying to turn the entire universe of thought and logic into formal objects ( such as the number 1, which is most definately *not* an object), is putting the dogma before the cart, which then drags the poor cart anywhere the dogma wants it to go.
"Aspect" Orientation simply feels like a sect trying to break off from the Mother Church to me. This is not to say it may not be very useful, but that usefulness is needed because of doctrine in the first place.
Some things are objects. Some things are just operations or functions that have to be tortured beyond recognition if they're to be objectified. The less "pure" an OOP language the more *useful* I tend to find it, because it allows me to choose my methodology based on the problem.
Aren't there easier ways to add one and one and get two?
KFG
Yes, and languages like SmallTalk and Ruby also allow similar constructs.....the one advantage I can see from looking at the AO extensions to Java is perhaps a little more clarity in being able to quickly see the melds between methods of disparate classes, but the functionality is no different.
I did see a project on sourceforge to add explicit AOP to Ruby, perhapss making code more understandable, but of course one can hook methods without it
A methodology hasn't made really made it until somebody has published a Proper Book.
:-)
What, like The Art of the Meta-Object Protocol by the very same Gregor Kiczales et al, pub. MIT Press, 1991?
Like most things, AOP is only new if you don't know LISP.
I took a look at AspectJ awhile ago and instantly spotted the hidden horror show for implementation: There is no test you can write to assure your aspect was applied appropriately. (at least there wasn't when I looked). Apparently nobody sees this as an issue? The application of aspects is essentially a blind process before compilation occurs. The best you can do is place errors in your aspect and break the compile. I can't imagine turning this tool loose on a development organization.
I have a second sig, I call it sig#2.
I think the reason there are so many 'huh? why do I want to do all this?' responses is that Java is not a language that lends itself to AOP, and that AspectJ therefore has to build this scary layer of 'pointcuts' and so on on top of it.
With a language that lets you assembly types dynamically, like Ruby or Perl, AOP is much simpler and more natural, so it's easier to get a feel for the benefits.
In particular I think Ruby is well-suited, although you do lose some type safety. There is a package called AspectR available, although you *could* do it all youself with mixins and the like.
Whence? Hence. Whither? Thither.
P.S. I don't dress fashionably either, prefering to save valuable beer money.
Modest doubt is called the beacon of the wise. - William Shakespeare
I bought it back in january, after first learning about AOP. At the time, it was the only book I could find directly on AOP, with a second coming in feb. Otherwise, the only other text source I could find was Generitive Programming.
So I bought it, and I was excited when I began reading. Then I found out it was just a bunch of JSP and other then the first 25 pages, very little content. Now I admit I put it down a good 25 or so pages later and skimmed through the rest, but I was extremely disapointed in it. Instead I've been grabbing all of the ECOOP workshop documentation.
In the end, it was worth the money. No, not for the book, god no! But by getting me excited and reading the ACM Communication articles and then talking to my adviser about it. It turns out the editor for the AOP material in the ACM communications is a professor at my school, and even better is happy to let me help her out next semester (I'm extremely swamped now). So now I'm considering doing the thesis option on my masters. I'll spend the summer reading REAL material.
My opinion: AOP is awesome but the book is a waste of money. Here are a few good readings:
Alternatives to AOP
Generitive Programming chapter
AOP publication
AOD 2002 workshop
ECOOP97
"Open Source?" - Press any key to continue
In short, used judiciously, this is a very, very handy tool. Used indiscriminately, this is an utter fscking nightmare. And anybody who lets the project's junior-level coders work with this should be taken out back and shot. Repeatedly.
Modularity, encapsulation, separation of concerns or whatever you want to call it is still a good idea.
Aspect Oriented Programming claims to support a new kind of modularity, but what it really does is break encapsulation.
Imagine you're responsible for a module in a big system. Over the years, well meaning aspect oriented programmers stick more and more little hooks into your code. Eventually like Gulliver, when you try to move, e.g. fix or improve your code, you simply can't without breaking the hooks that tie you down.
If they had used your published interface and you designed a good interface, you would have been ok, but no! They reached into your code and created dependences on your implementation. If it's production code and you break someone else's code, you'll be seen as the bad guy.
Many years ago I used Xerox Lisp machines and worked near the inventors of Aspect Oriented Programming. I used two precursors of AOP. I used the advice mechanism in InterlispD and later Active Values in it's object oriented extension Loops.
When used very sparingly, advice was useful, especially for debugging and working around bugs. The advise function allowed you to add wrappers to functions that would replace, preceed or follow the invocation of the function. You could further restrict the advice to apply only when a function was called from within another function.
Active Values, on the other hand, were an advice mechanism applied to object field access. People quickly realized that the facility was a mess because there was rarely any hope that you could get your advice to run *only* when you wanted it to and rarely any hope that you could avoid a unreadable tangled mess. There were new getter and setter functions that didn't trigger the active values, but this just added even more complexity.
It would be much easier to design an explict hooks than to worry about what happens if someone sticks an active value in any and every object field. Especially when the field may already have an active value.
It's vital to be able to assume that when you read a line of code, you know what it means and if not, you know where to look up what it means. Rather than enabling hacks like aspect oriented programming, we need better tools for making clean changes that sweep across the source code and thereby do away with the urge for this perilous patching stratgy.
I still dont understand how this is all that much different than event driven programming. Obviously its syntatically different than using event triggers, but is it conceptually?
Every example of AOP I've seen uses the "logging example" (is AOP actually useful for anything else?)
In this example some sysout is printed after certain method calls.
methodFoo();
methodBar();
both trigger message();
so what? Can't this be done with java style event handlers and triggers? Are there benefits of AOP beyond oberserver/oberserved type relationships?
I work my ass off and write a program and when I send it to my boss he's always sitting infront of his monitor at a different angle and it looks and works totally different.
Yes Francis, the world has gone crazy.
Aspect-oriented programming has been talked about for a while now, but it still isn't nearly ready for prime time. The obvious issues are that it will introduce bugs and that it will be at the same time very hard to debug.
The first goes without saying: every new technique can be considered a collection of novel ways that things can go wrong. Insofar as AOP is powerful, it will create whole new classes of bugs.
Things like AspectJ make things worse, though, because they are pre-processors. So debugging is going to involve tracing into machine-generated code. This does not need to be a nightmare, but somehow it almost always is.
There is also the issue of debugging your aspect specifications themselves, alluded to briefly in the article with the point about infinite recursion. I'm sure there are many other subtle and interesting bugs that AOP can introduce, and I'm very grateful to all the eager souls who are going to find and fix them over the next few years.
I think AOP solves a legitimate problem. I'm not by any means sure it's the best solution. In a few more years, when tools and techinques have matured a little, it may prove to be a valuable technique.
--Tom
Blasphemy is a human right. Blasphemophobia kills.
For those of you who are C++ programers and would like to see Aspects in C++ check out:
aspectc.org
They are at revision 0.6 but they do provide many of the useful features in AOP. My one beef is that they don't provide the ability to specify aspects based on the 'const-ness' of a function, but hey its only 0.6 and they have a way to go before 1.0
In Ruby:
1.times { puts "Hello World!" }
Now there are other ways of doing that that are almost as readable and almost as useful but isn't that neat? What makes treating everything as an object even more useful is that you can treat everything the same way. You can always say obj.inspect and get something useful out of it. This is great when you're debugging something and wonder: "What the heck is this function returning?", whether it's an integer, a hash or a complex object, object.inspect will always work.
Java makes things confusing by having both primitive types (int) and object types (Integer), because in some situations you want to be dealing with an object, but the language isn't flexible enough to let you treat the object form of an Integer the same way you would a primitive int.
What I think makes Ruby so cool is that essentially everything in Ruby is, or can be an object, but it doesn't get in the way.
I agree that languages that are inflexible can be rough because they limit your options, but how is treating everything like an object inflexible?
LISP programs are practically always unreadable. If it's unreadable, it's unmaintainable. Look at how all algorithms are laid out in CS books: that's structured programming. They certainly don't do a step, and then have you turn to another page to do the next step, and turn to another page to do the next step.
(tail (make (get (blah (foo()), bar())))))
In the end, this lang vs. that lang is "fundamentally superior" is all bullshit since practically all languages are Turing equivalent, so practical acceptance comes down to ease of learning, readability, API and platform support, speed, and sensible amounts of syntactic sugar.
Java does all those things pretty well. LISP had 50 years to gain acceptance, and it hasn't. It has had numerous evangelizers, even whole tech startups, and all for naught.
Hey, I'm just your average shit and piss factory.
I had a chance to read about AOP a few years ago, when it was first being introduced.
Short answer: Yes, it is the Next Big Thing.
In the same sort of way that procedures were already implemented by experienced programmers long before languages like Pascal came to be,
In the same sort of way that experienced programmers used virtual function lookup tables and information hiding before OOP came about,
So is AOP. It is program-language-level support for the sorts of things experienced programmers do already... namely, code generation and automatic code modification.
Basically the reason OOP came about was that there was no means to add functionality to code without going into that code and inserting a call to the new functionality. Experienced programmers made virtual functions and lookup tables to solve this issue, but obviously this sort of code is complex and prone to error. So OOP brought forth program-language-level support for this sort of feature.
The problem that AOP addresses is this: As powerful as OOP is, it still relies on functional decomposition. The trouble is, sometimes one thing changes that cuts across functional boundaries. For example, the performance of an application, when ported to a new system, may need an entirely different set of performance tuning for the new app. Or more likely, you simply didn't see some aspect (there's that word) of your code changing often, and it would be impossible to separate it into a module without restructuring your entire code.
Now you can do a lot of inline #ifdef's and the like to do this by hand. Or, you can use some sort of dynamic code generation. But writing a dynamic code generator by hand is, like the virtual function table example above, tricky and always ad hoc.
The ultimate goal behind AOP is to make code generation generalized and done at the language level. So that you can modify things that occur across the boundaries of the existing functional decomposition.
Does that make any sense?
If I remember correctly, in CLOS you can specify a method "foo", and then another method "foo" with the ":before" modifier that would be executed before the normal "foo" method. There is also an ":after" specifier.
Yes, and relational databases have had trigger methods before and after different SQL operations. You can define 12 triggers on a table in Oracle, made out of combinations of (before, after) (insert, update, delete) (for each row, for each statement). You code them in PL/SQL which is a fairly comprehensive language similar to Ada. Is AOP merely triggers for Java methods? Because you could do that already, by subclassing, overriding the method, and calling the superclass method within your own code.