Code libraries
When people first start using CFC's they often use them as a handy way to group related functions together. For example, if you could put all the functions that deal with users into the same cfc and you may have something like the following pseudocode:
User.cfc
function getUserName(id)
function getFirstName(id)
function getLastName(id)
function authenticate(username,password)
function getAllUsers()
function getUserCount()
function createUser(username,password,firstname,lastname)
function updateUser(id,username,password,firstname,lastname)
While this is a useful and valid way to use CFC's it isn't using them to their full potential.
Dealing with a single user
When working in object oriented way we try to discern what the different objects in a system would be. In this case User would be an object - and the user would know certain things about itself (name, username, password, date created) and just as importantly it would not know certain things (eg: total number of users in system)
User.cfc
var id //We store the user id in the cfc
function init(id)
function getUserName() //id is not required as it is already in the instance function getFirstName()
function getLastName()
function updateUser(username,password,firstname,lastname) //also no id required here
This "instance" of a user gives us access to all the properties that a user knows about but shields us from many of the functions that are not relevant.
We now have a user that we can easily conceptualise and work with without having all of the other methods such as getAllUsers() or getUserCount() getting in our way. It also allows a team of programmers to have a set of guidelines as to where code should live. If it deals with a single user it will be in the user CFC
But how do we create a new user
You'll notice that the above code has no way of creating a user - this is because it doesn't make sense for a user to be able to create another user (we're not talking about giving birth here). So how do we create a user.
We need a place to put the create user method that is outside of the User.cfc - and I have typically used something like UserManager.cfc.
UserManager is also responsible for all functions that deal with more than one user.
UserManager.cfc
function authenticate(username,password) // We don't have a valid user at this point
function getAllUsers()
function getUserCount()
function createUser(username,password,firstname,lastname)
This works really well in that there is now a logical place to put all of the code relating to Users and if all the people working on the application know where things should go.
Two CFC's for each object type?
However having two CFC's for each object type can get really messy, espcially when you are drawing Class diagrams. The java solution to this lies in the use of Static methods.
Static methods (or Class methods) are functions that are available on the Class as opposed to the Instance - i.e. when we are dealing with the concept of Users as opposed to a specific user Steve Bennett who works on level 5.
So now we are back to having the following:
User.cfc
var id
// static methods
function authenticate(username,password)
function getAllUsers()
function getUserCount()
function createUser(username,password,firstname,lastname)
function init(id)
//Instance methods
function getUserName() //id is not required as it is already in the instance
function getFirstName()
function getLastName()
function updateUser(username,password,firstname,lastname) //also no id required here
But aren't we back where we started with everything jumbled together? Not really, we now have a obvious set methods that deal with a single instance and another set that deal with multiple users.
In this example you only have half the number of methods to look through when you are dealing with a specific user (i.e. all the instance methods) and the same when you are dealing with multiple users.
Enforcing it in ColdFusion
However Coldfusion doesn't naturally handle the differentiation of Static methods from Instance methods - however with a bit of ingenuity (aka hackery) we can enforce it in our CFC's. I've got a working prototype of this and I'll post some more on it shortly.
Further reading
If you are interested in getting more aquainted with Object Oriented design I've found the following books very helpful: