A good user experience requires responsiveness. Speed. Web pages that don’t make you wait more than a couple of seconds while they load, or even worse, load in bits and pieces and reorganize themselves in front of the user; “that’s the way these things work” isn’t good enough an excuse. Your users don’t want to know how your site works (even if your site is about how the internet works – they want to read about the problems, not experience them), they just want to get things done and move on. As Eve says in Gaiman’s Fables and reflections, “Some people have real problems with the stuff that goes on inside them … sometimes it can just kill the romance”.
What we need, then, is a small number of reasonably sized files: how do we get to that?
Ok, But why bother?
The standard arguments for using AOP apply – you can maintain separation of concern, add new behaviours, and all that.
The final reason for bothering was, in my case, a very slow and boring evening. Hey, it’s my blog and I don’t need to justify my choice of subjects, k?
The sources provided with this post, are not only bad for production use, but they are also fundamentally flawed as we shall discuss in a little while. If you intend to use them as they are, remember that I’m not taking any responsibility for them, am not likely to maintain them, etc etc. If you find a use for them and don’t mind the issues, you’re free to use them, play with them, or otherwise modify them as you see fit.
Since they are so conveniently available, it’s possible to pass them as arguments to another function, which is what we’re doing in the Aspect(target, aspect, implementation) function. In the first argument, target, we state which function we want to apply an aspect to. In the second argument, aspect, we specify the aspect we want to apply to that function – in other words, the behaviour that will be added to the target function. The third argument, implementation, is used to define the sequencing of the call. This is, again, a function, which calls target and aspect in a given order.
The Aspect function can be called through one of three helper functions: AspectBefore, AspectOnSuccess, and AspectOnException. These three define a specific sequencing implementation. AspectBefore, for example, calls the aspect before calling the target.
Arguments, arguments …
Although we are now able to attach additional behaviours to the function, we still can’t do anything useful with them, because we have no way of controlling them. Without the ability to pass arguments to them, aspects would be severely limited.
Unluckily, this vital item is probably the flakiest part of the entire script. I’m using the apply method, which allows us to invoke a function with an array of arguments. This function appears to be deprecated, which means that it may or may not be around in future. The real problem though, is with the scope. You see, the first parameter of the apply function defines the scope of the call – it tells the function what the “this” keyword will refer to. As it is, the scope is fudged, and may not refer to what you expected in many circumstances. This is the main reason for the great big warning above.
While this was just a simple excercise to pass the time (and is by no means complete), everyone is free to tinker the results. If anyone actually manages to make something useful out of it, do let me know!