Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
ColdFusion Components and Data Abstraction
CFCs provide basic object functionality to CF developers part 2

In my last column we looked at using ColdFusion Components to abstract database access, essentially divorcing presentation code from anything database specific. As you will recall, the benefit of this was that when a database change occurred (a column being renamed, for example), presentation code was not impacted at all. In this column I'II take this concept one step further.

Beyond Simple Abstraction
First, let's review. Here is simple code to retrieve a list of employees:


<!--- Get employees --->
<CFINVOKE COMPONENT="emps"
          METHOD="list"
          RETURNVARIABLE="employees">

<!--- Display list --->
<UL>
 <CFOUTPUT QUERY="employees">
  <LI>#LastName#, #FirstName#</LI>
 </CFOUTPUT>
</UL>

<CFINVOKE> invokes list in component emps, which obtains an employee list. emps.cfc contains (as we left it last month), with two methods: list is used to obtain a list of users, and update is used to update an employee's name (see Listing 1). So far so good.

Components Are NOT Query Replacements
Thus far we've used CFCs and methods as simple query replacements. That's not a bad place to start, and if you were to never again use a <CFQUERY> in your .cfm files, that would be a very good thing indeed.

But CFCs aren't designed to simply be inline query replacements. In fact, CFCs need not map to database tables or queries at all. For example, if you had an online store you'd probably work with several types of components:

  • A customer component to provide access to customer specifics and any customer related processing
  • A catalog component used for catalog lists and searches
  • An item component used to obtain item specifics, as well as pricing, availability, images, and more
  • An order component
  • and so on
These components may map to tables. Internally, a customer may indeed be a single row in a database table. But then again, it may not. The truth is that internal storage doesn't really matter. What's more important is that components are logical entities used to encapsulate and abstract related functionality. In more understandable terms, components are like little black boxes that contain everything you need to perform specific operations for specific functions.

Components As Objects
This brings us to the subject of using components as objects. The best way to understand this concept is with another example. Look at the following code:


<!--- Get employees object --->
<CFOBJECT COMPONENT="emps"
          NAME="emp">

<!--- Get employees --->
<CFINVOKE COMPONENT="#emp#"
          METHOD="list"
          RETURNVARIABLE="employees">

<!--- Display list --->
<UL>
 <CFOUTPUT QUERY="employees">
  <LI>#LastName#, #FirstName#</LI>
 </CFOUTPUT>
</UL>

If you were to run this code, it would generate the exact same output as the previous invocation example. But something is very different here.

Previously, <CFINVOKE> was used to access a component and then invoke a method. It did both of those tasks, all in one tag. Here we have separated the component access from the method invocation. <CFOBJECT> loads the component as an object - the new object is named emp. This <CFOBJECT> call does not execute any method; in fact, no method name is even specified. It is <CFINVOKE> that invokes the list method in the already loaded component object. (Notice that #'s are used in the COMPONENT attribute in <CFINVOKE. This is because it refers to a variable as opposed to a file name).

The advantage of this type of access and invocation is that it allows for components to be instantiated (obtain an instance of) independent of any method invocation. This allows for multiple invocations against the same component (perhaps a series of inserts or updates). It also allows components to persist (to stick around, especially if the object is in a persistent scope like SESSION or APPLICATION). And it allows for alternate forms of invocation. Look at this example:


<!--- Get employees object --->
<CFOBJECT COMPONENT="emps"
          NAME="emps">

<!--- Get employees --->
<CFSET employees=emps.list()>

<!--- Display list --->
<UL>
 <CFOUTPUT QUERY="employees">
  <LI>#LastName#, #FirstName#</LI>
 </CFOUTPUT>
</UL>

Once again, the code here accomplishes the same result as in the previous examples, but notice that there's no <CFINVOKE> tag used here. Rather, a simple <CFSET> is used to save the results of emp.list() (the list method in component emp) to a variable named employees.

This form of invocation is used when working with objects, which is what the component here is being used as. Once a component is loaded as an object, it can be used in lots of different ways, and repeatedly too.

Methods, More Methods, and Even More Methods
Now you know how to use components as objects. Great. Now what? The next step is to define all sorts of methods in your component, methods for anything you may need to know about or do.

For example, imagine we had a second component we could use. Unlike emps.cfc which is used to access all employees (lists of employees), emp.cfc provides access to a single employee, and everything that you'd need to know about him or her.

Look at this simple invocation in Listing 2. <CFOBJECT> instantiates the employee object, just as we saw previously. But which employee's object is this? Actually, it's not associated with any employee - we'd need to do that ourselves. The <CFSET> statement invokes an Init method (as in initialize) and passes an employee ID as an argument (we've hard-coded it to 22 here, but you could pass a variable or any expression instead).

Once initialized, the employee object can provide access to everything you'd want to know about an employee. The GetName method (invoked as #emp.GetName()#) returns the employee name, GetStartDate returns the employee start date (which is formatted using the DateFormat() function), GetYears returns the number of years at the company, and EligibleForCar returns true if the employee has worked long enough to be entitled to a company car (hey, we can all dream!). Load the object once, initialize it, and then use it over and over as needed.

All of the code is presentation code. There is no database access, there is no logic, no calculations (as would be needed to figure our company car eligibility). All of that is buried in the little black box, the component. And once that component has been instantiated and initialized, all of the other methods can be invoked as needed.

So what does the emp.cfc component look like? And how does it remember the employee that it is associated with? The code is shown at Listing 3.

Component emp.cfc contains lots of methods. Init is an important one; it requires that an employee ID be passed to it as an argument, and it then uses it to query a database for employee details (using the emp_id in the SQL WHERE clause). The query name is THIS.emp, THIS is a special scope that refers to the CFC itself. As the query is placed into THIS, it persists for as long as the query does, and will be usable on subsequent method invocations. This is why, after calling init in the calling page, the code was able to make all of those subsequent method invocations. The GetName method returns an employee name, extracted from the saved query. The CFC need not query the database again, as the query created in init still exists (in THIS).

GetFirstName and GetLastName do exactly what their names suggest. They are not used in our example, but you will generally want to create all the methods that you may end up using at some point. There's no downside to doing this, and the extra effort up front will make the components far more reusable.

GetStartDate returns the employee start date stored in the table. GetYears uses the start date to calculate the numbers of years of employment. This is a great example of the type of calculation that's too often erroneously placed in presentation code (where it's used, but where it absolutely does not belong). The EligibleForCar method is similar; it does the calculation (need to have been employed for at least 5 years) and simply returns true or false. This type of calculation does not belong in presentation code, ever. Logic, business rules, data abstraction, all of that and more belong in CFC code. Presentation code is for, well, presentation.

We're Just Getting Started
We've just scratched the surface. CFCs are the most important enhancement to the CFML language since the language was first created almost a decade ago. At a minimum, CFCs should subtract all database access. I'll say it again, no more <CFQUERY> tags in your presentation code.

But beyond simple database abstraction, ColdFusion Components should be used for all data abstraction, including calculations, business logic, any data processing, and more.

Yes, it takes a little more time up front. But once you try it you'll be pleasantly surprised to discover that it really is just a little more time.

And the upside?

  • More reusable code.
  • More manageable code.
  • Performance gains (when using persistence properly).
  • Dramatically reduced risks when making changes.
  • The ability to easily replace or add presentation layers. (Need a Flash front end? Flex? Web services? Those are all alternate presentation layers against the same back-end CFC).
In other words, there's plenty to gain, and nothing to lose.

Summary
ColdFusion Components, first introduced in ColdFusion MX, provide the fundamental building blocks used to design applications the right way. They provide some of the power of objects while retaining the simplicity that is uniquely ColdFusion. In the last column we looked at basic data abstraction, separating data (and data integration) from presentation. This time we looked at encapsulating more than just data processing, persistence, and more. For your next project, you'll most decidedly want to use ColdFusion Components.

About Ben Forta
Ben Forta is Adobe's Senior Technical Evangelist. In that capacity he spends a considerable amount of time talking and writing about Adobe products (with an emphasis on ColdFusion and Flex), and providing feedback to help shape the future direction of the products. By the way, if you are not yet a ColdFusion user, you should be. It is an incredible product, and is truly deserving of all the praise it has been receiving. In a prior life he was a ColdFusion customer (he wrote one of the first large high visibility web sites using the product) and was so impressed he ended up working for the company that created it (Allaire). Ben is also the author of books on ColdFusion, SQL, Windows 2000, JSP, WAP, Regular Expressions, and more. Before joining Adobe (well, Allaire actually, and then Macromedia and Allaire merged, and then Adobe bought Macromedia) he helped found a company called Car.com which provides automotive services (buy a car, sell a car, etc) over the Web. Car.com (including Stoneage) is one of the largest automotive web sites out there, was written entirely in ColdFusion, and is now owned by Auto-By-Tel.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Latest Cloud Developer Stories
Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON Featured Whitepapers
ADS BY GOOGLE

Breaking Cloud Computing News

ANN ARBOR, Mich., Feb. 16, 2012 /PRNewswire-USNewswire/ -- In recognition of a $15 million gift t...