Frank Fusion

Sunday, 30 March 2008

Stricter OOP using AOP!

An application I wrote recently was exhibiting a strange bug. When a user added contacts to the contacts database, details from previously entered contacts were being inserted in fields that were left blank for the new contact. The client had entered over a hundred contacts before they realised that this was happening and were somewhat worried. After some investigation, I tracked down the cause of the problem: an accidentally unscoped variable in a CFC method.

In Object Oriented languages, an object's properties are explicitly declared in its definition; they are integral to the make-up of the object. To add or remove an object's properties during its life could be seen as mutating the object and an undesirable behaviour in a strict OO design (I do not believe it is possible to do this in C++ but I may be mistaken).

Due to the way we emulate OO in ColdFusion, such mutation is exactly what happened when I clumsily used an unscoped variable in my CFC; the variable became part of my object's 'integral make-up' resulting in the sneaky bug.

This made me wonder: how could I restrict my objects from ever modifiying their definitions by deleting or creating new variables in the variables or this scope during their existance?

The first, and so far only, useable answer I have arrived at is through using Aspect Oriented Programming (AOP). My implementation uses the ColdSpring framework although it could be done without it. For the AOP savvy, I simply created an around advice object that checks the target object's properties before and after any method execution - if there is an inconsistency, an appropriate error is thrown. The pseudo code looks like this:

BEGIN
SET variablesBefore = Get object's variables
EXECUTE object's method
SET variablesAfter = Get object's variables

IF variablesBefore <> variablesAfter THEN throw error
END


If anyone is interested in the Source code I can post it, just a PITA to put code up using blogger! Better solutions on a postcard.

Dominic

Labels: , , , ,

12 Comments:

  • Working source code (raw and requiring ColdSrping):

    www.dominicwatson.co.uk/downloads/statechecker.zip

    By Blogger Dom, At 30 March 2008 18:43  

  • what if the method is supposed to change the value of one of the object's properties?

    By Blogger me, At 30 March 2008 21:17  

  • Perhaps the pseudocode should be clearer - the values of the properties can change, yes. The equality check is checking whether there are any new variables or whether any variables have been deleted.

    By Blogger Dom, At 30 March 2008 21:49  

  • An interesting concept but not sure I like it. This introduces hidden complexity and overhead to protect an object from sloppy programming. This seems to violate good programming practice.

    By Blogger Adam Haskell, At 30 March 2008 21:55  

  • I'd agree with the complexity, unless you were already using AOP (it is a very straightforward AOP implementation). The overhead is not worth mentioning though as it will be so negligable.

    I am usually anal with my scoping, but one slip caused reasonably horrid results and was difficult to pick up.

    In my view, ColdFusion allowing such loose scoping 'violates good programming practice' especially in terms of OO. I agree that it would be better being much simpler (perhaps built in to ColdSpring (wishful thinking) or ColdFusion itself implementing OO more strictly (even more wishful thinking)!

    Other ideas on a postcard...

    By Blogger Dom, At 30 March 2008 22:06  

  • http://varscoper.riaforge.org/

    This may be a better solution. Alternately I think this would be a nice addition to unit testing tools which is where these types of issues should be caught.

    By Blogger Adam Haskell, At 30 March 2008 23:05  

  • Yeh, definately; I thought there might be some debugging tool out there that could do that - thanks for the link.

    I'd still like a clean way to have strict properties in cfcs though damnit!

    By Blogger Dom, At 30 March 2008 23:17  

  • Maybe this component could be coded in java - all the strictness you could ever want. If you've never tried a hybrid java/CF app, you might be shocked at how easy it is.

    OTOH, if this particular code must stay in CF, you just need to improve your unit testing. Trying to "undynamicize" CF sounds like a losing game to me.

    As for "sloppy" - well, to some people all dynamic languages are intrinsically "sloppy". If this is you, you're trying to swim laps in the kids pool with the slippery slide. You really need to get over to the big pool with the lane markings.

    By Blogger jmetcher, At 31 March 2008 01:54  

  • "...you just need to improve your unit testing"

    I love working with CF, this is just a minor grievance that I have with it. 'Always scope your variables' is constantly bounded around - better testing and being a better coder is one answer to avoid it; not being able to not scope your variables in the first place is another.

    The consensus seems to be, "don't use this feature - always scope your variables". I don't think I'm alone and I'd love a simple way to have my program crash when I break the rules that I want to enforce on my own code.

    I don't think this is asking much, certainly not so much as to want or need to write my model layer in another language.

    "You really need to get over to the big pool with the lane markings"

    lol nice. Though I disagree (see above)

    By Blogger Dom, At 31 March 2008 10:47  

  • Reread my post. OMG. Sorry about the catastrophic outbound tact filter failure on my part. I certainly didn't mean to imply that that you're a sloppy unit tester, or that CF is a kids language, or Java is somehow more adult. Just that the *kind* of strictness you want is totally in tune with the Java philosophy and kind of at adds with CF's super-loose approach. But given you want to nail things down a tiny bit more, your AOP solution is a nice idea and nicely done.


    It's actually kind of ironic that Java has this reputation as a "serious" language and CF as not so serious. IMHO, dynamic languages like CF require more mature skills, and Java is the system with the training wheels and all the safety nets (or lines on the pool to tell you where to go, to return to my earlier metaphor).

    By Blogger jmetcher, At 31 March 2008 23:51  

  • "Reread my post. OMG. Sorry about the catastrophic outbound tact filter failure on my part."

    Lol, I wasn't offended - its all valid and I think you agree with my point; the looseness provided by the language demands more strict restraint on the behalf of the programmer. I'm just scatting on a theme of enforcing my own strictness.

    "...your AOP solution is a nice idea and nicely done."

    Thanks ;) I'd like something simpler but I'm going to try it out on something and see how much of a PITA it is (shouldn't be)

    Dominic

    By Blogger Dom, At 1 April 2008 09:53  

  • I've been doing some more scatting on the theme and have managed to come up with a base component that does what my AOP component did (without the hassle).

    Will be blogging about it soon as it was fun and opens up other avenues.

    D

    By Blogger Dom, At 5 April 2008 05:20  

Post a Comment

Subscribe to Post Comments [Atom]



<< Home