Kiss My App

Sunday, November 28, 2004

Ego Tripping at the Gates of Hell

In my initial rant about AOP, I hoped to spawn some serious debate from the Java community over what and how AOP should be used, if it at all. Two very lengthy threads insued at TheServerSide.com and Sun's Java Forums. I was offered some good examples of AOP usage, some poor examples of AOP usage, and an abundance of hubris comments. To all I say, "Thanks!"

I spent some time reflecting on my original post and the examples/debates offered up on the forums. Not to spoil the ending for all of you, but I feel even more strongly against using AOP with OOP than before.

Both OOP and AOP work to solve the same thing-- encapsulation and inheritance. The difference is that OOP provides a vertical object model through inheritance and delegation and AOP provides a horizontal attribute model through pointcuts. When a developer writes code, he or she operates within a set of 'rules' as specified by the language to provide scope to the logic they convey in their code. By providing scope, code becomes easier to read and maintain-- you can logically focus your attention on a single scope of variables and state through the concept of objects. AOP advocates are correct in stating that aspects can provide the same kind of scope and encapsulation, but one is better than the other.

Point #1, who has the right to provide the behavior for an object-- the subject or the observer? An example is moving and displaying a collection of shapes. When a caller (the observer) calls methods to modify the state of the shape, does it have the right to notify the display that the shape has actually moved? Shouldn't the shape (the subject) be able to retain the knowledge of if and how it moved? What if shape's behavior changes, will the observer's behavior now have to change? The OOP solution for updating the display would be to let the shape notify any listeners that it has in fact moved. The AOP solution is to update the display any time I call a method on shape where I think it will cause it move. Compile-time weaving or not, we've just broken the shape object's encapsulation and added code to our system that has to be maintained seperate from shape itself.

Point #2, AOP can make OO code act in unnatural ways. JBoss AOP provides an 'asynchronous' annotation to methods. The idea of taking a method and by simply adding an annotation, have it be asynchronous for everyone that uses it (the callers). First off, the method probably wasn't meant for asynchronous operation and the caller doesn't necessarily have the right to now declare it as such. Secondly, the JBoss asynchronous aspect introduces code changes to the way all callers now interact with the method. If the goal of AOP is to encapsulate behavior, this aspect is a complete 180. Referencing my first point, through AOP we've just changed the behavior of the subject through observation. An OOP solution would be to delegate the call while providing a literal asynchronous method signature, encapsulate asynchronous implementations in your delegator. If I want to use the method as written, unmodified, I can still call it directly. If I want the method to be called asynchronously, then I can be the special case and use a delegator.

Point #3, AOP with OOP now creates a bidirectional inheritance model. What does that mean? Your code can now be a pain to maintain. That is probably the biggest issue AOP proponents had with my original rant. Developers now not only have to trace the vertical object model, but also the horizontal attribute model as provided by aspect pointcutting. Developers everywhere are asking themselves, "Where's the beef? Where's that behavior coming from? Where's that variable being set? I don't know!" It might just be an IDE issue to some, but to me it's a logical issue. I can logically follow a single java class on a piece of paper, I can't say the same for all of the aspects that might be weaved at compile or runtime.

In summary, where do I see any benefit to AOP? In decorating my code, not my application. This means that AOP can be used for things like logging/tracing the code I write, but never to dictate application behavior or state. It really has no business in my application. If you find AOP as a wonderful solution to issues during implementation, then you are going about OOP the wrong way. The only thing AOP does is provide encapsulation for procedural programming.

8 Comments:

  • I agree with Jacob. I think it's kind of hacking the OO code, where the OO code have no knowledge of how the AOP code is going to behave and how it is going to change the behaviour of the application. What if the AOP code has a bug? A OO+AOP developer cannot step-in thru the code of the AOP also !!! :-(

    r-a-v-i

    By Anonymous Anonymous, at 12:38 AM  

  • You obviously do not have a clue about AOP. You talk about one specific issue about JBoss AOP; If that all you know about AOP, I suggest you should write a rant about JBoss/AOP, not about AOP.

    Both OOP and AOP work to solve the same thing-- encapsulation and inheritanceWhile it can be said that OOP and AOP have similar agendas, encapsulation and inheritance are obviously not the problems being tackled. They are OOP means to achieve the goal.

    Point #1, who has the right to provide the behavior for an object-- the subject or the observer? [...]This not an AOP vs. OOP issue. It's a design issue.

    The OOP solution for updating the display would be to let the shape notify any listeners that it has in fact moved. The AOP solution is to update the display any time I call a method on shape where I think it will cause it move.Where the hell did you get the idea that OOP dictates one solution and AOP and the other one ? Some AOP frameworks may make it easier to implement the caller side solution, but it does not mean that it's the only solution supported by AOP. It think it would be more correct to say that the AOP solution is that you won't have to introduce by the hand the code to notify listeners.

    Point #2, AOP can make OO code act in unnatural ways. JBoss AOP provides an 'asynchronous' annotation to methods.[...]The point of AOP is not to force anyone to use asynchronous method calls when it's not appropriate but to let anyone switch to asynchronous with a snap of the fingers if they think it's appropriate. It's not caller vs. callee or observer vs. subject, it's about doing doing the right thing in an efficient and elegant manner when both sides are coupled to form an application.


    Point #3, AOP with OOP now creates a bidirectional inheritance model. What does that mean? Your code can now be a pain to maintain.[...] I can logically follow a single java class on a piece of paper, I can't say the same for all of the aspects that might be weaved at compile or runtime.You remind me of some people who were used to procedural languages and had to jump into OOP. You can follow a single Java class, but the point of OOP is not have a signle class, but to make use of inheritance at some point. When a class calls an inherited method defined in an other class, do you think "it's hard to follow" or "it's great code reuse" ? AOP pushes abstraction a step further than OOP, and it makes thing more difficult to grasp for the people used to OOP because they think they have less control over what's going on. But the real fact is that AOP gives you more powerful tools to control the global behaviour of a program.

    One of the benefits of AOP is that you can reuse aspects, so you are not going to have to debug aspects for every application you develop. You will have ready for use bug free aspects that you can use in your applications, just like ant framework or library. But you won't have to introduce thousands of lines of codes spread all over your classes. The definition of a few pointcuts will do.


    In summary, do write arrogant rants about something you don't really know, it can only help make a fool of yourself.

    By Anonymous Anonymous, at 6:22 AM  

  • You obviously do not have a clue about AOP.I wish you could enlighten me as to why I don't have a clue about AOP? Am I and everyone else using it wrong? I used to think AOP was great and loved what it could/can do (bought and read a couple books on it in the process)-- even spent a couple months using AspectJ. But then I did even more reading-- not on AOP, but on OOP and realized that AOP isn't that necessary if I would have properly used OO in the first place.

    You talk about one specific issue about JBoss AOP; If that all you know about AOP, I suggest you should write a rant about JBoss/AOP, not about AOP.JBoss AOP was only one, albeit very popular example of real world use of Aspects.

    While it can be said that OOP and AOP have similar agendas, encapsulation and inheritance are obviously not the problems being tackled. They are OOP means to achieve the goal.By pointcutting behavior in a single place across a set of methods, doesn't that provide encapsulation of behavior within an aspect-- also being able to extend that aspect to provide alternate capabilities?

    AOP pushes abstraction a step further than OOP, and it makes thing more difficult to grasp for the people used to OOP because they think they have less control over what's going on.Catch yourself on that one-- doesn't that make the code counter intuitive to other developers? Do we want to make our code more difficult to grasp?

    But the real fact is that AOP gives you more powerful tools to control the global behaviour of a program.In referencing the third paragraph of this blog, developers operate within a set of rules that provide scope to what they are doing, allowing other developers to quickly understand what's going on by reading the code. It's not that you cannot read and understand an aspect itself, but without additional tools, it's hard to understand how all aspects could interact within your application since AOP breaks the vertical object model and operates in it's own variable/behavioral space. It's the same thing as declaring global variables all over in your program in a procedural manner. They are a pain to maintain and determine who is modifying what and when.

    One of the benefits of AOP is that you can reuse aspects, so you are not going to have to debug aspects for every application you develop. [...] But you won't have to introduce thousands of lines of codes spread all over your classes. The definition of a few pointcuts will do.Same thing as OOP, as stated in my original argument. Using basic OOP principals, you get the same thing-- composition, delegation, encapsulation, and inheritance. If you have to introduce thousands of lines of code spread all over your classes, maybe you aren't properly programming in OO?

    In summary, do write arrogant rants about something you don't really know, it can only help make a fool of yourself.Please offer actual examples in your next reply, instead of more hubris comments. -- Happy Holidays!

    By Blogger Jacob Hookom, at 9:55 AM  

  • (from Gregor Kiczales)

    You say "If you find AOP as a wonderful solution to issues during implementation, then you are going about OOP the wrong way."

    But in the thread on TSS, you failed to provide an answer to my challenge of re-writing the DisplayUpdating/ObserverPattern aspect, so that it had the same modularity properties, but without AOP. You mumbled something about a solution, but no solution was offered.

    What's important about the DisplayUpdating example is that its the smallest example I know of that shows why the "just use objects properly" argument is bogus. You can't do that example, with those design qualities, using OOP. Any OO solution is going to be scattered and tangled and difficult to evolve.

    The line about the puppies was good though.

    By Anonymous Anonymous, at 3:16 PM  

  • Gregor, you are correct in that AOP provides a simpler solution to the subject/observer issue you described, I don't want to take that away from your original post. I wanted to point out if the behavior actually belonged in an external entity, not within the object itself (despite the need to maintain it in a super object or delegator through composition-- like PropertyChangeListenerSupport). The comment about using OO properly is my suggestion that object models can accomplish the same *goal* as AOP while preserving the core intentions of OOP in general. Hence my OO suggestion of being able to register movement listeners with shapes, allowing them to notify changes of their own, internal state.

    By Blogger Jacob Hookom, at 4:07 PM  

  • (also from Gregor Kiczales)

    I will stop after this.

    The Listener approach has many problems the AOP approach doesn't have. Three of the most important are:

    Efficiency -- listener dipatch is dynamically typed, iterates through collections and so on. In AspectJ and AspectWerkz for example that's statically typed and compiled out.

    Ease of evolution -- what if you don't realize you want the listener right away? Or what if the arguments to be passed to it change? Or what if you later want to take it out?

    Comprehensibility -- the listener just tells you that SOME listener is called. Not which one. The AspectJ IDE tools tell you exactly what is called.

    By Anonymous Anonymous, at 6:46 PM  

  • I don't agree at all. AOP is complementary to OOP. Using AOP correctly you can implement cross-cutting functionallity that usiong pure OOP would be very difficult to implmenent and maintain. I used AOP for a large project and found it extremelly useful... i think AOP is not dangerous at all i handled with care.

    Greetings, Nicolás Dijkstra

    By Anonymous Anonymous, at 9:22 AM  

  • I made a comment on AOP on my blog as well http://www.livejournal.com/users/trajano/16104.html

    I have a sort of anti-AOP stance myself. Reading the stuff you had here does add fuel to the fire.

    Although I do know it has its uses, especially in avoiding the fragile super class anti-pattern. Its still a bit iffy for me.

    By Blogger Archimedes Trajano, at 10:11 AM  

Post a Comment

<< Home