My CFC methodology
I’ve been thinking recently about my coding style. I’m always interested in doing things in the most elegant and efficient way possible and the methodology I use these days is a result of many years of experimentation and refinement.
I think a coding style, from formatting and file structure to app conceptualisation; is a delicate balance between personal preference and the conventional wisdom of our peers. Well structured and thought out code is easy to maintain and a joy to return to, but inconsistent code can easily become unwieldy.
I wanted to share some examples of the way I’ve come to structure things – Perhaps someone will find it useful, or perhaps others might share their own methodology and I may learn something!
Today I’m looking at my ColdFusion components
I like to create CFCs that can be reused across projects, and so I’ve found that I often add more and more functions and over time these components can become difficult to manage.
My methodology now is to split each function into separate files, including them in the CFC code itself. It’s a simple concept, but the result is that it's easy to see from a glance in the filesystem which functions are in a given component, and all are easily editable.
The problem with splitting your functions out into separate files is finding an efficient way to include them in the CFC. To this end, I now use CFML file operations to automatically include .cfm pages from all sub directories.
This means we can also split functions up in to separate sub-folders to group them together. For a large CFC, it's really rather zen like. ;)
Here’s a look at a typical CFC using this trick:
<cfcomponent
name = "CFCDemo"
output = "false"
hint = "A demo of my CFC Methodology"
displayname = "CFCDemo"
>
<cfscript>
// Set CFC name
Variables.CFCName = 'CFCDemo';
// Set folders
Variables.CFCFolder = GetDirectoryFromPath(GetCurrentTemplatePath());
// Get CFC files
Variables.CFCFiles = DirectoryList(Variables.CFCFolder, true, 'query');
</cfscript>
<!---
Init function
--->
<cffunction name="init" access="public" returnType="any" output="false" hint="Constructor">
<cfargument name="DSN" type="string" required="true" hint="Datasource" />
<cfset Variables.DSN = Arguments.DSN />
</cffunction>
<!---
Include CFC files
--->
<cfoutput query="Variables.CFCFiles">
<cfif Variables.CFCFiles.type EQ 'file' AND ListLast(Variables.CFCFiles.name, '.') EQ 'cfm'>
<cfinclude template="#(Variables.CFCFiles.Directory & '\' NEQ Variables.CFCFolder ? ReplaceNoCase(Variables.CFCFiles.Directory, GetDirectoryFromPath(GetCurrentTemplatePath()), '') & '/' : '') & Variables.CFCFiles.Name#" />
</cfif>
</cfoutput>
<!---
Memento
--->
<cffunction name="getMemento" access="public" returntype="struct" output="false">
<cfreturn Variables />
</cffunction>
</cfcomponent>
What we're doing here is using DirectoryList to return a query object containing all the files in the current folder and sub-folders. If these files have .cfm extensions, they're included in the CFC itself. It's important to specify .cfm
files only, as if you're using version control or comparison tools, backup files can easily sneak into the folder and be included in the CFC automatically.
I'm using a mixture of tags and CFScript here as I'm still more comfortable with tag based CFCs even though most of my logic is written in CFScript these days. Each to their own, ay?
So, how does this compare with your own methodology? I'd love to hear some opinions.