Tuesday 2 October 2012

Native event framework for ColdFusion 11 ?

G'day:
ColdFusion 11 development is - apparently - underway, so I've turned my mind to what I'd like to see in CF11. One of the things I have been trying to do (with very limited success, I hasten to add) is to learn some new languages. Both with a view to moving on from ColdFusion development eventually (be that via jumping, or being pushed...), as well as it being useful to know how other languages do stuff, and bring some of those techniques back into one's day-to-day work.


For example I was reading a book on C# (which is a cool language!) and this got me thinking about event-driven approaches to coding, and later I was writing some Javascript stuff (for my revised UI fur the Adobe bugbase search), and I was able to leverage some of the concepts from C# in my JS. I don't mean listening to UI events like one is doing all the time in Javascript (onclick, onmouseover, etc), but having the application components fire and listen to events by way of intercommunication. I've got a form that announces that it needs some stuff, which the search proxy listens for, then fires a search when it hears it, and that announces it had some results when its finished getting them. The results table listens for that, and when it hears it, renders the results (which are in an argument passed by the event trigger). I rather like it as an approach! None of the parts of the app know about each other, there's just a bit of init code that says "right: you listen out for this; you listen for this one; and you listen for something else". The bits of the app just need listeners that know how to deal with the event, but they're all decoupled.

This got me thinking that this approach could work really well in ColdFusion too.

First things first I had a fossick around to see what was already out there.  I had a look at a few of the frameworks out there to see what they did by way of event handling. I think I had a look at Model-Glue - which doesn't seem to be under active development any more? - CFWheels, FW/1 and ColdBox. And - somewhat surprisingly - drew pretty-much a blank.  ColdBox was the only one that dealt with anything like this, but - if I'm honest - I wasn't convinced by its implementation.  That said this was based entirely on reading the docs, and at some point I'll mess around with the code and see what I think then.  I'm sure the CB implementation works great in the context of a CB site, but it did all seems implemented in a very platform / expectation-specific sort of way.  I guess this makes sense in a framework, but I was looking for a more generic solution.

The other thing I found was a CF implementation of the observer pattern, which is good an excellent implementation of the pattern, and I'll think I'll use it, but because it's a generic/baseline implementation - it's a coupla interfaces - it does require work in each CFC that participates in the pattern.  What I'm after is something that works like how JQuery does it: there's a method on() which binds an event handler to an object that might trigger an event, and another method trigger() that announces an event has happened.  I want that sort of simplicity in ColdFusion (and that sort of simplicity better maps to ColdFusion's approach to making complex things easy).

But there are practicalities to consider in this.  JQuery has this overarching object that manages all this, and every object that one wants to use on() / trigger() needs to be wrapped in a JQuery object, which isn't necessarily a good fit for ColdFusion.  Although I suppose they could be part of /WEB-INF/cftags/component.cfc, as all CFCs extend that. However this only deals with CFCs... I'd still like to be able to trigger or declare events in a CFM / non-object situation though.

So then I though - I hasten to add all this thinking is just stream-of-consciousness stuff, and not necessary well-informed notions - that perhaps the on() / trigger() methods could be implemented as methods of each scope, meaning code could do this:

// listen for an application-wide event
application.on(
    "myEvent",
    function(event, data){
        // etc
    }
);

// trigger an application-wide event
application.trigger("myEvent", data);

(and similarly for session-specific or request-specific events).

But then I thought this would suck a bit if I wanted to trigger an application-wide event within a CFC, because it kinda breaks encapsulation to reference the application scope within a CFC method.  Hmmm.  So maybe it could be like this:

// listen for an application-wide event
on(
    name = "myEvent",
    handler = function(event, data){
        // etc
    },
    context = "application"
);

// trigger a context-wide event
trigger(name="myEvent", context="application", data=data);

So we specify a context for the event to reside in.  I don't see the context here to be limited references to CF scopes (like "application" or "request"), but could be anything, really.

Or... some other approach..?  What do people think?  Not only about how to approach event handling in CF, but the idea of it being something to add to CF in the first place?

--
Adam