Inheritance without extends: a practical use case for class based mixins
What I’m doing now is moving all of my code out of the class files into a set of method files that can be mixed in. I have written a simple includer within each class (I still need to have stub class files as the physical path to the .cfc is used to define the class identity and to provide package/protected methods) that calls a single script which contains all of the rules about how to build the classes for a given object and includes all of the appropriate subfiles. The approach currently supports a one method per file approach (UserDAO-getUserList.cfm, UserDAO-saveUser.cfm, etc.). It is also fairly easy to set precedence rules so project specific custom methods overload generic custom methods which would in turn overload generated methods which in turn would overload base methods. You just start with the “most custom” directory and keep a list of all of the methods included.
There may well be some performance downsides to getting rid of inheritance, but by having all of my methods in a methods directory (just as I have all of my components in a .com directory) it would be pretty trivial to write a publisher that would publish traditional component files using traditional extends based inheritance if that provided performance or other worthwhile benefits. In the meantime this approach gives me a huge flexibility that is useful for software product lines and generated applications.
I also like the fact that browsing my directory structure gives me an immediate view of the methods available and that I never have to scroll up and down through 500 or 1000 line class files to find the method I’m interested in.
If I was committed to traditional IDE based development, I’m guessing this would be more of a step backwards than forwards as IDEs are optimized to work with class files, not method files, but as my goal is to transcend IDEs and generate almost all of my code I find this to provide a more flexible approach as it is easier to merge lots of little method files into the appropriately composed class files automatically than to write a parser to pull methods from different class files to restructure my classes based on dynamic business rules.
This may end up as no more then an experiment, but I’ll build a basic project today and release a sample zip file tonight along with LightWire so people can see an alternative approach to application design where methods aren’t constrained into specific cfcs. As with all of my code, sizeable projects will be dependent on intelligent dependency engines – you can’t just drop a UserDAO-getUserList.cfm into a ProductService method and expect it to work. However, by breaking out methods and treating them as first class citizens it allows for either automated or manual dependency documentation so you KNOW all of the implicit dependencies of each method (maybe getUserList() depends on a variables.UserTableName variable – that should be documented in the metadata so you never mix in that method for a given project without making sure you have that property).
Now we’re starting to move towards a world where specific applications with all of the necessary internal dependencies can be auto generated using class based mixins at runtime which will be fine for proof of concept purposes. And if there are performance or other issues, it would still be easy to add a “publish” step to create a set of fully formed class files either with all of their methods in a single file or using a traditional inheritance tree via extends without having the limitations of class files grouping your methods at design time. The approach also allows for traditional cfcs so you only have to use the mixins for classes that change substantially between applications. LightWire.cfc, for instance, would still just be a single cfc.
I’ll let you know how this goes!
[UPDATE] I didn't find this to be worth the trouble. See my next post for the lowdown.



Given that most of my postings display my ignorance of various topics, it seems appropriate that the occasional comment should also come from a place of less than universal knowledge!
Believe it or not, you can indeed mix in methods to classes either using cfinclude to add them to an entire class or just a simple cfset to add a method dynamically to an individual object and they have full access to the variables scope of the instantiated objects they are mixed in to. Try it for yourself!
Both Hal Helms and Sean Corfield have good posts on this including one Judith Dinowitz helped to put together for Fusion Quarterly.
Seans presentation: (PDF FILE) http://corfield.org/articles/ducktyping_cfunited.p...
Vy a Duck: http://www.fusionauthority.com/techniques/4588-Vy-...
and if you Google Coldfusion and mixins or "duck typing" you'll find a bunch of other resources.
What techniques have you developed for avoiding name collisions? How do you make sure two mehtods injected into a class don't try to create variables using the same names (and therefore overwriting each other's values)?
I'm working on a set of dependency resolution tools for my metadata which I use for generating methods, but at the end of the day, there is no formal mechanism for safe name resolution any more than there is a way of making sure you don't overwrite variables scoped values between methods in your class files. As a practical matter I tend to have pretty strong conventions for what gets to set something in the variables scope. In singletons I only allow the init method to set regular properties and the AddObject method to add dependent objects as part of my LightWire IoC/DI engine. In business objects I have a private mutate("PropertyName") generic base business object method which is wrapped both by a base setter and by and custom setters, so in practice the likelihood for naming conflicts is pretty small the way I develop things.
I would be much more leery of a lot of dynamic programming techniques from mixins to not typing a lot of my arguments and return types if I was working as part of a larger team.
As for ensuring you don't add multiple methods to the same object with the same name, that is a solvable problem with StructKeyExists() for object based mixins or with a little clever parsing if you're using cfincluded. The trick is to set a couple of properties in your cfc file (they are available at mixin time, not after the object has been instantiated) and then to call a general cfincluder that can pull all of the right methods from the right directories and follow your business rules to ensure you don't copy multiple methods with the same name into the same class.