One of the biggest reasons to move towards using OO concepts with Coldfusion is to build modular, extendable code libraries which are very easy to reuse throughout an application or group of applications. As a start, we'll begin by moving queries that generally return multiple records into Gateway objects.
Changing your code perspective
If you've gone through my Mach-II Primer, you've probably started rethinking how you arrange your code. If not, let's start with some old school, procedurally programmed Coldfusion code:
This outputs something like:
The query qContacts will usually return a record set containing more than one record. These types of queries are generally placed into a Gateway Object.
As outlined in the first four parts of this primer, the object ContactGateway.cfc has two functions:
The constuctor method init() takes a single argument which is the value of the datasource. Since the same datasource will be used for every query throughout this application, it will be placed in the variables scope of the object.
This function wraps the same query that has been moved over from the CFM page. Notice that the name of the query has been var scoped, making qContacts a function local variable.
The only change to the query has been to value of the datasource. Instead of reading from the request scope of the CFM file, it's been placed into the variables scope of the object via init().
So how do I get the data now?
Instead of writing the query on the same CFM file that will output its results, we'll create an instance of the Gateway Object and access the query through it.
What about user specific data?
First, let's expand our database a bit. We'll add a Users table and a UserContacts table.
Next we'll have to update our query to bring back only Contacts associated to a specific User or all Contacts if no user is specified.
Finally, we need to change how we're requesting this data. Let's assume that the currently logged in user's UserID is stored in the variable session.userID.
So if Mr. Potter is logged into the site, the page should only output
You could easily reuse the same code in an Administrative section of the application, where one user can control others, as well as alter records associated to them. If you had a list of Employees, you could pass the EmployeeID through a URL variable to the same function in order to get their contacts.
Reducing calls to createObject()
As the code stands now, the ContactGateway.cfc object is created every time the page is requested and placed into the variables scope of the CFM file. Also, this object is used by every user of the application, but there is no user specific data stored in the variables scope of the CFC file.
Rather than creating the object over and over, it can be created once and placed into the application scope. This places the object in memory for the life of the application, reducing processing time and the overall memory usage of the application.
The simplest place to do this is in the Application.cfc file inside the onApplictionStart method. This will ensure that the object is created and placed in the application scope when the application is loaded for the first time.
Now we can remove yet another line of code from our CFM file:
I can't say that you should place a Gateway object into the application scope 100% of the time, but I can say that you should do it more often than not.
What does this accomplish?
Instead of a single file containing a query and HTML, we now have two files with even a little more code than when we started.
By splitting the code into two files, we gain two things:
- There is a reduction of the amount of code in a file that comprises part of your application's user interface (UI), a file that is commonly referred to as a View.
- The query is now available to the application as a reusable chunk of code via a Gateway object, making it part of the application's Model.
Placing the object into application memory drastically reduces page load times and helps to decrease the overall footprint of the application.
Even if you don't use a published framework like Mach-II, Model-Glue or Fusebox to develop your application, separating code that belongs in the Model from code that manages the View can not only simplify your initial development process, it can reduce future development as well.
We can handle multiple records in the Model, now we need to deal with them one at a time. Next we chase down the elusive Bean Object.