Copy link to clipboard
Copied
Hello CF Superheroes,
I'm playing around with CFCs and I've run into a situation where I would like to start calling methods from some CFCs from within another CFC (nesting). My first instinct was to simply instance the CFCs from within the parent level CFC but I'm not sure ColdFusion would like it if I nest CFCs like that. I've read about some people getting the dreaded "null null" error at times.
I'm aware of the "extends" property from within the <cfcomponent> tag but the problem is that you wind up having to instance all of the extended CFCs in the calling CFM template anyway. It seems like it would just be easier to call the CFCs from within the CFCs that need to be "extended".
For example, here's what I'm thinking of doing:
In my main template index.cfm:
<cfobject component="MasterCFC" name="cfcs.master">
<cfset temp = masterCFC.myFunction()>
Then within master.cfc:
<cfcomponent>
<!--- get my sub cfc --->
<cfobject component="SubCFC" name="sub">
<cffunction...>
</cfcomponent>
Otherwise (as I understand it) if you wanted to use the "extends" property you would have to do it like this:
In my main template index.cfm:
<cfobject component="MasterCFC" name="cfcs.master">
<cfobject component="SubCFC" name="cfcs.sub">
<cfset temp = subCFC.functionFromMaster()>
Then within sub.cfc:
<cfcomponent extends="master">
<cffunction...>
</cfcomponent>
I'd love to hear your thoughts on how you nest CFCs or "extend" them efficiently.
Dave
G'day Dave
There's no trick here. To call a CFC's method, you do this:
<cfset pearsCFC = CreateObject("component","cfc.pears")>
<cfset pearsCFC.green()>
And this doesn't change whether yer in a CFM or a CFC.
So given this requirement:
<cfcomponent>
<cffunction name="green">
<cfset applesCFC.red()>
</cffuntion>
</cfcomponent>
The answer is:
<cfcomponent>
<cffunction name="green">
<cfset applesCFC = CreateObject("component","cfc.apples")>
<cfset applesCFC.red
...Copy link to clipboard
Copied
You have to see the problem from Object-Oriented perspective, which allows you to extend and re-use your code.
I highly recommend that you read Refactoring: Improving the Design of Existing Code Martin Fowler, et al. This book contains rich information about object-oriented design (code sample in Java).
It depends the nature of your problem, but in most cases I would use extend if I want to have another class that behaves similar to parent's. In other word, it's inheritance.
This kind of design decision is covered in Fowler's book.
Copy link to clipboard
Copied
Thanks for the book suggestion. I'll look it up.
From what I understand about object oriented programming (and it sounds like you're defintely more of an expert than I am so please forgive me if I am mistaken) both methods I suggested take advantage of code reusability and use a modular (object-oriented) design approach. I guess what I was asking is if there is a clear advantage/disadvantage of using the first approach (nesting CFCs) over the second (Extending).
I'm not familair with Mr Fowler's approach to object oriented programming so his book might clearly indicate that extend is the preferred method rather than nesting but when I draw out both methods on paper, the cleaner approach seems to be the first one (nesting). Can you please share some light on why the second approach is better than the first?
Copy link to clipboard
Copied
I'm afraid you basically misunderstand how OOP works, both in general and as it applies to CFML. The explanation of how OO "works" is outwith the scope of someone banging away at a keyboard on a forum, and is basically down to you learning your craft.
I've not read it nor heard too much about it, but Matt Gifford has written a (short) book on OO programming for CF: http://www.amazon.co.uk/dp/1847196322. I do know that Matt knows his stuff and has been working in CF for years, so it'll be accurate. You should get hold of it and read it. Or just read free online resources on how OO works, and then the relevant CFML docs to get an idea of how CFML does OO.
As it stands, until you understand the basic concepts that you want to work with, it's not really worth asking questions about it. (I don't mean that to sound dismissive; just matter-of-fact).
--
Adam
Copy link to clipboard
Copied
Thanks Adam for the response and for the link to the Matt Gifford book. I'm definitely not an expert when it comes to object oriented programming, but I've been using ColdFusion for many years and I'm just now transitioning into using CFCs instead of just a bunch of UDFs. Perhaps if I simplify my question you could show me how you might solve this little predicament in your own style?
Lets say you have two separate CFCs and you would like to call a function from CFC1 from within CFC2. How would you go about doing that? Here's some sample code to help me explain my problem:
CFC1: ApplesCFC
<cfcomponent>
<cffunction name="red">
</cffuntion>
</cfcomponent>
CFC2:PearsCFC
<cfcomponent>
<cffunction name="green">
<cfset applesCFC.red()>
</cffuntion>
</cfcomponent>
Index.cfm (The calling template)
<cfset applesCFC = CreateObject("component","cfc.apples")>
<cfset pearsCFC = CreateObject("component","cfc.pears")>
<cfset pearsCFC.green()>
Thanks in advance for your patience and for taking the time to assist.
Dave
Copy link to clipboard
Copied
G'day Dave
There's no trick here. To call a CFC's method, you do this:
<cfset pearsCFC = CreateObject("component","cfc.pears")>
<cfset pearsCFC.green()>
And this doesn't change whether yer in a CFM or a CFC.
So given this requirement:
<cfcomponent>
<cffunction name="green">
<cfset applesCFC.red()>
</cffuntion>
</cfcomponent>
The answer is:
<cfcomponent>
<cffunction name="green">
<cfset applesCFC = CreateObject("component","cfc.apples")>
<cfset applesCFC.red()>
</cffuntion>
</cfcomponent>
One thing to watch here is that you need to VAR your variables in your methods, otherwise they're global to the CFC instance, rather than local to the function.
--
Adam
Copy link to clipboard
Copied
Thanks Adam. Yes, scoping vars in functions is very important. I typically always create a scoped structure called "o" and then put everything within the function inside of that structure to make it easier.
Dave