Overall, Simon's post led me to think that people may have gotten the wrong impression from my posts on this topic.
First, I am, in no way, advocating the use of the <cfinclude> tag inside of a CFC's method. That would be insane.
Second, nothing in a <cfinclude>-style Mixin template should live outside of a <cffunction>.
Third, nothing in the Mixin template's <cffunction> should add to, and preferably not alter the existing scopes of the target CFC - the Mixin's methods should be observational in nature.
Ok, on to my reply:
Joe'd like me to elaborate, so I will.
Code within a <cfinclude> is neither encapsulated nor parameterized.
I think you're taking my use of <cfinclude> very far out of its context. It's being used only to bring <cffunctions> into an existing CFC ? nothing in the included .CFM exists outside of (encapsulated, parameterized) <cffunction> tags.
The code within the <cfinclude> I discussed is both encapsulated and parameterized ? not in an Object sense, but in a Function sense, because a Mixin is *not* an Object, but more like a fragment of functionality. It's a template, not a component.
The call to include the code is also parameterized. I needed an API that was limited in scope, making Mixin implementation simple and limited. In fact, the only parameter I wanted to be able to pass was the .cfm file to use as a template. <cfinclude> is exactly that API.
There are some basic rules of OOP that I firmly believe in and apply to CFC use. One is that all business logic belongs in CFC methods.
Agreed ? but how those methods get into an instance doesn?t necessarily need to be from a .cfc file.
Another is that CFCs don't ever display anything ? their methods are data in and data out.
Given those two facts, what good can come from using an include within a CFC method?
If you look at what I did, I never used a <cfinclude> inside of a CFC method. I think doing so would be pretty silly.
If the thing being included contains business logic then that code should be in a method.
All of the business logic in the <cfinclude> was in methods. That?s the point ? importing of methods.
If anything, this [code in a method] is more reusable than having it in an include file.
The include *only* contains methods that need to be re-used across CFCs without inheritance. I?m not sure you read what was being <cfinclude>?d in my example?
If the thing being included generates output, it's OK for that code to talk to CFCs but should never be used by a CFC (since they shouldn't be writing to the screen).
100% agreement. (S)he who <cfinclude>s something into a CFC that creates output has gone way, way astray.
I'm still waiting for someone to give me an example where using inside of a CFC makes more sense than having all of your logic in components.
?Mixing? is the only example, and only case, where I can find <cfinclude> as being appropriate in a CFC. Even in this case, the included CFM would have to follow strict rules: no output, no code outside of <cffunction> tags, and preferably ?observation-only? interaction with the private/public scopes of the target CFC.
It?s a very dangerous thing to do, with limited (good) application. I?m up front about that, and I?m taking steps with further Model-Glue development to eliminate the reason I?m doing it in the first place. The example I blogged is about the only good place I can see to do what I did.
Mixins appears to me like a convoluted way to implement the Aspect Oriented Programming technique of 'weaving'.
Yes, it?s similar. Weaving and Advice are somewhat more advanced AOP concepts that deserve much more robust mechanics than <cfinclude>.
I used <cfinclude> instead of implementing my own AOP mechanics because it?s intentionally simple and limited, and not convoluted in the least. I needed a mechanism to statically add a template of methods to a CFC ? and <cfinclude> works like a charm.
Weaving aspects is an interesting idea, but I wouldn't choose to use <cfinclude> in order to implement it.
Neither would I! Doing AOP cleanly in CF would require a library to not just provide method injection/inflection mechanisms, but one that could also resolve the injected/inflected methods and their dependencies as well! Come to think of it, this already sounds familiar.
this entry is pretty long already, but if anyone out tere would like to see me implement AOP in CFML, I don't mind doing it.
See ColdSpring AOP ? it's already been done, with the full power of an IoC container behind it :)