Who what when of cfc's, custom tags and cfincludes
I've developed these rough guidelines over the past few years:
CFC's
This is the most heavyweight level of encapsulation in CF and one of the most useful. It allows you to group togther functionality relating to a particular aspect of your application. e.g. for an ecommerce site you might have a product.cfc which deals with a single product and a productManger.cfc which deals with multiple products.
What do you put in a cfc:
- Anything complicated - if the code requires some thought to understand what it is doing then it should be in a cfc - this makes it easier to test, easier to reuse, and is typically not web-accessible which is a bonus for security.
- Business logic - anything that comprises business rules - i.e. function calculating the discount that should be applied to an order, or checking if a product is available
- Any hacks (aka shortcuts) - it happens to all of us, deadline approaching and we make some huge assumption that we suspect will come back and bite us. If we put the "hack" into a cfc it contains it to a single place and makes it easier to come back and fix it later.
Rules for cfc's:
Never* read from a global scope - always pass all variables in (we bend this rule with datasource names) Never* write directly to the screen (output always false) - return as a variable insteadScope: arguments, variables (private), this
cfimported Custom Tags
These are the perfect complement to CFC's as they are primarily used for rendering to the screen. The should almost always be output tags and should have all the relevant info they need to do their job passed in via attributes.The way custom tags and particularly cfimported custom tags are used in code make them fit naturally as display code. They slot into your html and are simply tags on steroids.
Inheritance
Can import multiple directories with the same tag prefix - we typicall import our core/ui functions and our application specific ui templates under the ui prefix. The order of the import statements is important as if there is a name conflict then the 1st tag loaded is the one that is used (which may not be what you expect)
Rules for custom tags's:
- Never* read from a global scope - always pass all variables in (we bend this rule with datasource names)
- Never do any business logic - use cfc's for that
- Display logic is allowed - but if complicated consider moving to a library function
- Don't try to do too much - one custom tag one job!
Scope: attributes, variables (private)
Regular Custom Tags
Called by the cf_customtag or cfmodule - they have all the same properties and attributes as above but to my mind are more awkward in the way they are called. Some may disagree with me - but I believe that CFC's and cfimported custom tags give an super flexible way of developing.
Includes
Shared scope - useful for grouping some repetitive code or for mix-ins.We often us it to store email templates which are sent by cfc methods. In this case the CFC has a sendEmail method, but for ease of editing the content of the mail is loaded from an include.
The main reason not to use cfinclude is that it doesn't have it's own scope, and so it can be difficult to test and lead to spagetti code if not tightly controlled.
Scope: no private scope - shares scope of calling template
UDFs
UDF's were revolutionary in their day (for CF) but have been superseeded to a large extent by CFC's. Instead of using UDF's I typically group our generic functions into cfc's in a package structure. Eg all string functions live in the string.cfc and list functions in list.cfc.
Scope: arguments, variables (private)
Conclusion
ColdFusion provides an incredibly powerful and flexible combination for development with CFC's and imported custom tags. It give simple readable code for front end development and well encapsulated cfc methods for backend business logic.* Never in this case means unless you clearly understand why you should break this rule.




There are no comments for this entry.
[Add Comment]