BLOG
6 October, 2004
Method Reuse Without Inheritance
I've been experimenting with "mixins" in ColdFusion - a sort of Claytons inheritance where one component can bolt on one or more component's methods dynamically at run-time without having to extend them. Here's an example:
<cfscript>
// Create a mixin
eventMixin = createObject("component", "EventMixin");
// Create an object with no relation to the mixin
myObject = createObject("component", "MyComponent");
// Add some methods to myObject
eventMixin.mixin(myObject);
// Use the new methods
myObject.addListener(someListener);
</cfscript>
I got the idea from Actionscript but it actually works quite well in ColdFusion too, because you can pass function references around and dump them in scopes wherever you like. When I attach the mixin methods I temporarily inject a mixin init method into the target component and use it to set instance variables in the unnamed scope of the component (may as well take advantage of the broken cfc encapsulation - all variables put in a carefully named structure to avoid collisions) which include a reference back to the original mixin component. This last point is nice because I can then use the original mixin component as a central sorta-static-singleton for methods and variables shared across the components that have been mixin targets.
The nice thing about mixins is that you don't paint yourself into a corner with a big inheritance hierachy. Mixins are great for the "has-a" cases where you want to reuse code without the reuser having to marry into into the original code's family tree.
Comments
Robin: intriguing approach.
Have you read Hal Helms's newsletter article about implementing interfaces in CFC's?
We're very interested here to know how your mixin works. Could you post / mail source for the EventMixin in your entry?
-- Laurence
Comment made by Laurence Middleton / Posted at Thursday 07 October, 2004 01:10
It is indeed an interesting approach - we've used a similar approach to create a 'mixin' style persistence framework: you follow on some very loose conventions when writing your persistable components (you use variables.instance as a struct to contain anything you want to persist) and then you hand your component instance to the framework whereupon it inserts the CRUD methods it needs in order to deal with persistence of your component!
Hal's approach is a generalized form of the Employee-Role problem. A lot of people new to OO mistakenly think that Manager is-a Employee and if they implement it like that they quickly get into a world of hurt. Instead Employee has-a Role and Manager is-a Role. Which is exactly what Hal shows but with multiple roles named for the base class type that they represent. It's not really interfaces per se but it comes close (and it doesn't rely on method-injection hacks like Robin's mixin or our persistence framework!).
Comment made by Sean Corfield / Posted at Thursday 07 October, 2004 08:10
Stay tuned, I'm just tweaking and testing the mixin code for public release. I'm including some examples - event, property and caching mixin components to start with, with factory and pool components to follow.
Comment made by Robin Hilliard / Posted at Monday 11 October, 2004 11:10
The mixin code is available here:
http://rapide.tigris.org
Comment made by Robin Hilliard / Posted at Friday 25 February, 2005 04:02
Could you package it up into a single file. Other than the contents of the CVS repository, there are not files.
Comment made by Chris Velevitch / Posted at Tuesday 01 March, 2005 01:03
Post Your Comments