Reputation: 7597
I have been asked to update an old project. When i went into the cfc file it had over 3000 lines of code and over 100 cffunctions. I was wondering if i could split the cfc into multiple files whose cffunctions are logically grouped without having to change the code in any other pages.
Upvotes: 1
Views: 523
Reputation: 1435
It's an old question and I just came across it randomly, but I thought I'd chime in here as it's something I've had to deal with on many occasions.
If the goal is simply to organise things better from a code management perspective (rather than say, to specifcially reduce the amount of methods in each CFC) then I'd advocate breaking the CFC down into multiple CFM pages and including them in the CFC. From a code management perspective, you can group several functions into a well named CFM file and it all becomes a lot easier to deal with. The calling code remains the same, as all the functions are still being instantiated in the CFC as before.
I have a bit of code I use in my init methods that automatically includes all the CFM files it finds in the same folder, and I house a single base.cfc in each folder along with the grouped functions.
e.g.
<cfscript>
// Set CFC name
Variables.sCFCName = 'appUtils';
// Set folder
Variables.sCFCFolder = GetDirectoryFromPath(GetCurrentTemplatePath());
// Get CFC files
Variables.qCFCFiles = directoryList(Variables.sCFCFolder, true, 'query');
</cfscript>
<!--- Init function --->
<cffunction name="init" access="public" returnType="any" output="false" hint="Constructor">
<cfargument name="DSN" type="string" default="" hint="Datasource" />
<!--- Set DSN --->
<cfset Variables.DSN = Arguments.DSN />
<cfreturn this />
</cffunction>
<!--- Include CFC files --->
<cfoutput query="Variables.qCFCFiles">
<cfif Variables.qCFCFiles.type EQ 'file' AND GetToken(Variables.qCFCFiles.name, 2, '.') EQ 'cfm'>
<cfinclude template="#Variables.qCFCFiles.Name#" />
</cfif>
</cfoutput>
Upvotes: 0
Reputation: 2539
Run into a similar problem. I created the new cfcs and modified the original functions to call functions within the new cfcs.
For e.g
<cffunction name="GetStuff" access="remote" returntype="Struct">
<cfreturn createObject("component","myNewCFC").GetStuff(argumentCollection=arguments)/>
</cffunction>
Upvotes: 5
Reputation: 9971
Question implies there's enough client code using this object that changing the calls elsewhere if the object's broken apart apart is burdensome. In this case treat the existing object as a Facade - that is an object that provides unified interface to an underlying class hierarchy.
The way to approach producing the hierarchy is identifying those functions that should go together. Whenever I come across this problem the functions usually do not share any state, rather they are like static
java methods, but if there are functions that share state they are a good candidate for this grouping. Otherwise it's usually functions that share the same input parameters or tend to have the same verbiage in their name (i.e. saveMyData
, loadMyData
, etc...).
Given that example, copy these functions into a new CFC (e.g. MyData
) - at this point you may change the function names to eliminate repetition or improve their clarity (e.g. MyData.load()
). Back in the original object (i.e. BigCFC
) remove these functions' implementation and instead delegate the call to the newly created CFC (you may consider making the new CFC part of the old's composition). So it would look something like this:
<cffunction name="loadMyData">
<cfargument name="id" type="numeric"/>
<cfreturn variables.myData.load(arguments.id)/>
</cffunction>
Where variables.myData
would be setup as part of the CFC's initialization.
Taking this approach means your existing client code is unaffected by the change, but still breaks apart everything into logic groupings, and positions new code to use the more granular CFCs.
Upvotes: 2
Reputation: 32915
Refactor, Refactor, refactor...
simplest way might be using cfinclude
to inject functions (mixin's)
Upvotes: 2