Slashdot Mirror


Aspect-Oriented Programming Considered Harmful

kupci writes "The 'x considered harmful' cry is a little overused, but there is a Forrester report that discusses some of the pro's and con's of Aspect-oriented Programming, and includes some interesting links. It is mainly based on papers from the University of Passau. It's worth it just for Clark's 'COME FROM' article." From the article: "Aspect-oriented programming (AOP) is intended to address common problems that object-oriented programming (OOP) doesn't address well, plus some problems that OOP itself created. However, AOP is a risky solution: It is a very generic mechanism for solving some very specific concerns and has been likened to a kind of "GOTO" statement for OOP. Like GOTO, it can cause more harm than good."

25 of 470 comments (clear)

  1. Of course by ravenspear · · Score: 4, Funny

    The only thing worse would be GOTO + OOP, which of course = C++

  2. For those unfamiliar with AOP by ravenspear · · Score: 5, Informative

    Wikipedia linkage

    In computing, the programming paradigm of aspect-oriented programming (AOP) centers on constructs called aspects, which treat concerns of objects, classes, or methods. The aim of AOP is to separate program code related to the main purposes of the application (its core concerns) from code related to secondary purposes (cross-cutting concerns).

    For example, a telecommunications application might have a core concern of routing calls, while code for timing and billing those calls would crosscut the whole object hierarchy. AOP aims to separate the billing concerns from the core concern. It moves code not related to solving the domain problem from the business logic into a separate module. The application code no longer contains pieces of crosscutting concerns scattered across modules; instead, programmers maintain crosscutting concerns in aspects; this makes it easier to maintain both core and crosscutting concerns.

    Any program has principled points (join points) where programmers can identify and modify the program semantics. In AOP, programmers specify join points using a language feature called a pointcut, and specify the behavior to join those points by using advice such as methods or functions. Some variants of AOP allow programmers to extend the types in the system. These features enable aspects to implement behavior for concerns that crosscut the core concern of the application.

    1. Re:For those unfamiliar with AOP by starling · · Score: 5, Insightful

      Any program has principled points (join points) where programmers can identify and modify the program semantics. In AOP, programmers specify join points using a language feature called a pointcut, and specify the behavior to join those points by using advice such as methods or functions. Some variants of AOP allow programmers to extend the types in the system. These features enable aspects to implement behavior for concerns that crosscut the core concern of the application.

      Excuse me, but was that supposed to mean something?

    2. Re:For those unfamiliar with AOP by Keeper · · Score: 4, Insightful

      Let's say you've got objects a, b, and c.

      Objects a and b do something useful (the core of the application)

      Object c (an aspect) wants to perform an operation when something happens in object a (a concern).

      Object c (an asepct) also wants to do different things when something happens in object a and b (crosscutting a concern).

      I look at this as a really complicated event notification system. Comments calling this 'goto for OOP' also seems rather appropriate.

    3. Re:For those unfamiliar with AOP by snorklewacker · · Score: 4, Informative

      If you want something to happen when a certain thing occurs, wouldn't you just call a function or a method when that whatever occurs? Why would you want a goto style statement there?

      The whole idea of AOP is that it's not a GOTO. The "interceptor" (or whatever the jargon of the week is) gets called, does its thing, returns, and your original function runs. This is nothing, lisp does this with defadvice, even emacs lisp can do this (and indeed emacs lisp makes good use of it).

      The neat thing about aspects is that you define them in ONE place. So you tell it "I want function setup_db_connection() and teardown_db_connection() called before every method on any Person, Room, and Resource" (imagine it's a scheduling app). This is just like subclassing, but you don't have to rewrite anything else in the app. In fact, VB programmers who did this sort of hook trickery actually did call it subclassing. If you use a factory pattern, you can do this sort of thing without AOP, but the idea of AOP is to not force you to rewrite everything to use factory patterns -- you just define the "aspect" once, in one place, and it affects everything you tell it to.

      I find AOP is a great way to impose "external" conditions like debugging, extra asserts, and tests. I don't think it's necessarily a great way to structure an entire program, though someone with more experience in the methodology might make it work. As a new methodology, it's rife with shoddy implementations, buzzwords, overuse, poor use, and general immaturity. This is how all methodologies start out however -- even structured programming went overboard when it was first introduced to the mainstream.

      --
      I am no longer wasting my time with slashdot
  3. $249 by Anonymous Coward · · Score: 4, Interesting

    who is going to shell out that cash for 5 pages?

  4. Oh gee by Anonymous Coward · · Score: 5, Interesting

    "Powerful language constructs can be dangerous when misused"

    Thank you for the wonderful advice and welcome to 1971!!

    As for the GOTO comparison, it is disingenuous. The problem with GOTO is not that it is a flow control change, the problem is that it is an [i]unstructured[/i] flow control change. AOP is nothing if not structured, in fact its potential flaw lies in that the structures it represents can be so complicated the programmer can lose track. It's the absolute opposite of GOTO.

    1. Re:Oh gee by Bodrius · · Score: 4, Insightful

      No, the problem with GOTO is that, as a consequence of being an unstructured flow control change, it makes it impossible to trust your reasoning about code because it destroys your ability to scope it.

      To quote: "... it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress ..."

      I think Dijkstra's point was that any construct that does this is harmful.

      Structured constructs are typically less liable to do this, but only because they are visible and the structure is known.

      AOP does have the ability to inject arbitrary code in your function that can change its semantics and you cannot see this when reading the affected code.

      No matter how structured that change is, its invisibility makes it impossible to fully understand your code from the source code without 'weaving in' all the aspects explicitly. Like GOTO, it destroys your ability to scope your reasoning of the code to the local view.

      As much as I love AOP for a class of problems, this is a very valid concern that needs to be addressed.

      It's certainly not the first language featureset that faces this problem; OOP can deal with its own issues with design by contract, either through documented best practices or by enforcing it in the language. I haven't seen much in AOP there, beyond the absence of problematic examples (which would typically come from real-world use).

      --
      Freedom is the freedom to say 2+2=4, everything else follows...
  5. Re:Good primer on aspect-oriented programming? by Alien+Being · · Score: 5, Funny
  6. Executive Whining by idsfa · · Score: 5, Insightful

    There's a new idea in field I am incapable of getting a job in that is gaining in popularity among people I wish cared about my opinions. Buzzword I am dissing is intended to address common problems that buzzword everyone likes doesn't address well, plus something into which I have no insight. However, buzzword I am dissing is a risky solution: Complaint which betrays my ignorance and has been likened to somthing everyone hates. attack by analogy. Buzzword I am dissing will find some uses among people I secretly envy, but for the needs of (me) typical application developers, language gurus would do better to write something I can understand. My paper is important, pay me $50/page to read it.

  7. I like GOTO! by Wabbit+Wabbit · · Score: 5, Insightful

    At the risk of being modded troll, nuking my karma, being yelled at, laughed at, and otherwise folded, spindled, and mutilated, I'm gonna say it:

    I like GOTOs. GOTO has it's place. Even in C++. Sorry all you purists, but there are times when it just plain works.


    *runs and puts on Chinese wicker fighting suit and hides, trembling, behind a flame-retardant wall*

    --
    Nothing is inexplicable; only unexplained -Tom Baker, Doctor Who
    1. Re:I like GOTO! by evvk · · Score: 5, Interesting

      Plain C:

      void foo()
      {
      do some thing
      if(error)
      goto err1;

      do something more;
      if(error)
      goto err2; ....

      return;

      err2:
      free stuff
      err1:
      free more stuff
      }

      For anything else I shun goto.

    2. Re:I like GOTO! by Keeper · · Score: 4, Informative

      The goto operation can be rather useful if used sparingly and correctly. If I see a goto jump up (earlier in the function) instead of down, I tend to get worried. But it is useful to break out of nested loops or complicated logic statements.

      It is also exceedingly useful for error handling, in that it allows you to skip the bulk of a function and still hit the cleanup section of the function. This gives you two things:
      1) you avoid a deep, deep mess of nested if statements
      2) you eliminate duplication of code in error handlers (and the bugs that occur later on when someone forgot to update one of those handlers to release some resource they just added)

    3. Re:I like GOTO! by Keeper · · Score: 4, Insightful

      Gotos in C++ are limited to the same method, so no stack problems there.

      Exceptions incur an obscene performance hit, and should be used for 'exceptional' conditions and not expected/handled errors. You also have to worry about the case where someone else adds another exception handler that inadvertantly 'catches' your thrown exception (which makes for maintainance problems later down the road).

    4. Re:I like GOTO! by top_down · · Score: 5, Informative

      You have to catch [execeptions] at every point to free stuff, and the nested structures become even uglier than gotos.

      The freeing of resources, all resources not just memory, is automatic in C++ once you learn to use RAII.

      Look it up. It is one of major improvements of standard C++ over C/C++.

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
    5. Re:I like GOTO! by top_down · · Score: 4, Informative
      Show me code how to assign callbacks.

      Sure. This is an example using the boost::function and boost::bind libraries which have both been available for a long time and are in the process of becoming part of the standard C++ library.
      #include <iostream>
      #include <boost/function.hpp>
      #include <boost/bind.hpp>

      using namespace std;
      using boost::function;
      using boost::bind;

      void hello() { cout << "hello from function" << endl; }

      struct Object {
      void hello() { cout << "hello from member function" << endl; }
      };

      int
      main()
      {
      // callback with a normal function
      function<void()> f(hello);
      f();

      // callback with a member function
      Object o;
      f = bind(&Object::hello, &o);
      f();
      }
      If you don't want to use libraries just assign function objects or static class functions.

      If you want to do several callbacks at once check out one of the many available signal/slot libraries.

      --
      Anyone who generalizes about slashdotters is a typical slashdotter.
  8. best tool for the task by sfcat · · Score: 5, Interesting
    I like OO but is isn't great for every task. For instance, logging (which is the default example for AOP) is really bad in OO. This is because you have to add something like

    Log.printLog("some message " + someObject.toString());

    everywhere you want to log something. But with AOP you can used kleen operators (*, +, ?, etc) to add Log.printLog() to certain methods of certain objects. Aspects allow you to inject code into method call boundaries. But like all programming constructs it can be abused. This is because you might get an exception stack trace that indicates a specific method call has thrown an exception when the exception came from code inserted by an aspect. But other languages can be abused too (Perl anyone). So I think this type of critism of aspects says more about the critic than about the programming construct. I don't use C++ to implement logic evaluators (I would use Prolog or another logic or unification based language). Nor do I try to write OO code in LISP (despite the horrid OO extensions for LISP) because each language has it strengths and weaknesses. For each application choose the language that best suites the task.

    On another note, I think these types of critisms are really from people who are afraid of learning new languages or skills. They have worked long and hard to get good at C (or Java or some other language) and don't want to have to learn another language. Well suck it up, there aren't many Fortran programmers anymore and if you want to keep working, you must keep learning new languages and skills. Not that you should jump on every bandwagon, but if I'm writing something that needs to be really, really fast I use C. If I'm writing something that needs to be maintainable forever and speed isn't that important I use Java. The best tool for the task.

    --
    "Those that start by burning books, will end by burning men."
  9. Side effects++ by evvk · · Score: 5, Insightful

    The bad thing about AOP is that it adds lots of side effects to function calls and can thus make the program very hard to reason about. This is completely orthogonal to (purely) functional programming that intends to remove side effects thus making it easier to reason about programs.

    Functional programming: f(1) == f(1) always, with no other effects to "global state" etc.

    Imperative programming without AOP: f(1) != f(1) necessarily at every point of the code, as the function can access globals. It can also change the global state, so its effect is more than returning its value; it can have side effets.

    Imperative programming with AOP: Same as above, plus the side effects may happen somewhere unrelated to the definition of f itself.

  10. Forrester is just another clueless IT consultancy by tyates · · Score: 5, Insightful

    The big IT consultancies like Forrestor, Meta, gartner, etc are intellectually bankrupt. If you want an example, read the free article off of Forrestor's web page on IT metrics. It's absolutely worthless. Believe it not, it says that you should evaluate your IT department based on a balanced scorecard that is calculated by, among other things, the number of steering commitee meetings you have. Yes, you read that right, the more meetings the better your department is.
    These consultancies ran out of ideas a long time ago, and are trying to turn IT ito some Six Sigma pseudo-science. It doesn't work, but idiots still buy into it because it sounds impressive.

    --
    Tristan Yates
  11. classic newbie blunder by Anonymous Coward · · Score: 5, Funny

    You've attempted to assign C++ to a complex left-hand-side expression (GOTO+OOP). This is a classic blunder. What you probably meant was: "GOTO"+"OOP" == "C++".

    In addition, you're overloading the use of strings to have orthogonal meanings, which is frowned upon. After all, using the standard string operator overloading, your left-hand-side "GOTO"+"OOP" is simply "GOTOOOP", which is clearly not equal to "C++" -- a good comment compiler would notify you that this expression always evaluates to false. A further refinement would be to introduce your own class and write the expression as:
    LanguageFeature("GOTO")+LanguageFeature("OOP") == LanguageFeature("C++").

    In the future, I hope slashdot will provide a better comment compiler that can automatically detect such simple mistakes.

  12. Very true. That's what i told them at IBM HRL by dharmax · · Score: 4, Interesting
    When i worked at IBM research labs, i criticized AspectJ using almost exactly the same words: they try to solve specific issues (logging, persistency, etc), that deserve specific solutions, using a completely generic approach. They failed to provide more examples for those specific problems that AspectJ will solve. Of course, i was silenced - because that's the way it works in IBM Haifa - they just can't deal with criticism :)

    The concepts behind AspectJ, TMO, are not bright. They break encapsulation, they are too ambitious and far from real-world understanding of programming concerns. All in all, they introduce too many problems.

    TMHO,Aspect Oriented Programming should be different, and should be based on something much simpler, much more down-to-earth ideas and more consistent with real-world needs.

    Today it is easily possible to do using Java Annotations, that will specify class member's affinity with an aspect, and thus provide:

    A) a mechanism by which the compiler could limit access (errors & warnings) to members according to their affinity with a common aspect or aspects (common to it and its caller);

    B) a programmer, using a proper IDE, can view a breakdown of his code according to aspects.

    C) in runtime, the current aspect should be visible to the program thus extending the ability to: I) log, and trace errors; II) affect work-flow according to the aspect in action (that's an intense feature so im not too sure about that)

    Doing more than the above, looks to be like an abuse of proper programming concepts.

    The Annotation mechanism introduced in Java 5 is quite powerful and maybe already provide all that is needed for the job, including hierarchical arrangement of aspects (slash annotations), attributes, etc. Very little is needed in order to implement what i propose.

    Maybe i'll propose is to the JCP. What'd ya think?

  13. Software Patents Considered Harmful by Minna+Kirai · · Score: 5, Interesting

    And since Aspect-Oriented programming is a patented technique, basically nobody can legally use it unless you're a personal friend of the inventor.

    So, who really cares if its theoretically any good, when legally it is worthless?

  14. AOP sound in principle by triksox · · Score: 5, Interesting

    I've been following AOP (cautiously) for some years now. Here's a few salient points for those who don't have $250 to splash out.

    The underlying principle of AOP is about "separation of concerns", a term introduced by Dijkstra back in 1974. Separation of concerns is a Good Thing[tm], but there's more than one way to do it. It's a conceptual thing more than it is any one particular implementation technique.

    Both structured and OO programming offer techniques that allow the hacker to more clearly separate concerns: by organising their code into subroutines, modules, objects, methods and so on. The problem with OOP is that real world problems don't always break down into a set of clearly defined, independant object classes. In some cases you can end up with a problem fragmented into so many small pieces that you can no longer see the wood for the trees.

    AOP tries to address this by allowing you to identify those concerns that don't fit neatly into an object model. These "cross-cutting" concerns are typically things like logging, debugging and security that affect many of the objects in your system. If you decide to change the way logging is handled, for example, you don't want to have to go and edit every single object that generates logging information. But that's often what happens in OO based systems - you design your class hierarchy with Products, Customers, Orders and other real-world entities in mind and implement them as "black-boxes" with internal functionality neatly hidden away. That's fine when the functionality really is local to the object, but not when it relates to a system-wide aspect like logging, etc. These are the kind of undesirable artifacts that can arise from the decomposition of a problem into objects.

    However, that's not to say that there aren't ways of achieving the good parts of AOP in a non-AOP language. Many Design Patterns are examples of separating concerns. The Model/View/Controller and Model/Visitor patterns come immediately to mind. Going back to the early logging example, we could implement this in AOP fashion in an OO language, by creating a "Logger" object which implements all the logging functionality. Just make sure all your other objects delegate to the logger for logging rather than trying to do it themselves. Now you have all your logging code in one place, and you just have to worry about how you're going to pass the logger object around so that all your other objects can call on it... (and this is often the start of the rest of the problems...)

    So AOP-a-like can be done in OO languages, but most OO languages aren't really cut out for it - you have to code the magic manually if you want it. Hence the rise of AOP languages (usually just bolt-on syntax additions to existing languages) that make this process that little bit easier.

    AOP in Java does smell a little like GOTO, IMHO. In brief, it uses "join points" to connect different aspects together (e.g. call this logging method just before calling that other method). One can certainly argue that it's a more structured form of GOTO, but I believe the same fundamental problems remain: control flow jumping all over the place, with actions-at-a-distance waiting to catch out the unsuspecting programmer.

    So my advice on AOP would be to treat it like OOP, XML, Java, and all the other "silver bullets" that over the years have claimed to be the next big thing that will save our collective software sanity. Recognise the problem that it's trying to solve, realise the benefits of the particular solution(s) presented, and ignore all the hype!

  15. Objective-C has these, and no one bats an eyelash. by israfil_kamana · · Score: 5, Informative

    A very well respected (if a bit obscure) OO language is Objective-C. It has a few features that are analogous to aspects.

    First it has categories, which allow you to add new methods, or replace the implementation of a method in a given class. You add a category to that class that includes, say, a replacement description method, and the new implementation replaces the old. Or you can add a path utility methods to the String class, as another example.

    It also has "poseAs", which allows you to insert an object into a hierarchy. Say you have Class B which extends Class A. But you want custom behaviour to be accessible to all As children (including, for example, B). You create Class C, which extends A, and make it poseAs Class A. Now the runtime hooks all clesses that inherit A off of C, which replaces A. A still exists, but is in the background, providing normal inherited functionality to C.

    These abilities were one of the things that made Objective C a very powerful OO language. In particular, it allows a particular kind of reuse, by virtue of allowing one to patch someone else's library without having source. So if you want to add the aforementioned path utilities to NSString, you just added a Category in your own code, and your code would run with the extended functionality in NSString (no one elses would, unless they used your category too). This means that often you can make the most out of someone else's code without a complete rewrite.

    It isn't all powerful. There are access and visibility restrictions. It is also used to partition code for ease of organization and better modularization. Here's the point:

    Because it is a well known feature of the language, you think in terms of categories, and you know to look for categories. This can be aided by tools, but you most definitely need to pay attention to them. But because of this, they are only "dangerous" if you aren't paying attention. And guess what! That's true of programming, period.

    --
    i - This sig provided by /dev/random and an infinite number of monkeys at keyboards.
  16. AOP has its uses (without going to production!) by bsletten · · Score: 4, Informative

    AOP is not the answer to everything, but one of the main points of a talk I give at the NFJS show is that you can find tons of uses w/ development aspects without ever having to migrate them into production.

    You can enforce (and detect violations of) various architectural decisions (i.e. no direct JDBC connectivity without going through a facade), define and enforce contracts (and leave them out of production), detect threading issues (How would you find all Swing thread abuse cases in a large, multi-threaded application?), get a sense of code coverage, etc. around any arbitrary cut of your system.

    If you take the time to build around interfaces and support Object decoration via some variant of factories, you can do some of these things using Decorator and Dynamic Proxies, but you don't always have that luxury.

    Tool support has been fundamentally lacking until things like recent versions of the AJDT. It still isn't perfect, but should serve to answer many of the early critics complaining about debuggability and losing track of what is going on.

    I am an advocate of AOP in production systems, but you don't have to drink the whole glass to find aspects tremendously useful in development alone. With support for Ant-based builds and whatnot, it isn't even really an onerous task to give it a try.

    Don't use AOP for things it isn't a good fit for, but there are quite a few things that can't be done as easily and elegantly without it (at least in Java). As others have pointed out, languages like Lisp and Objective-C have support for AOPish things built in.