15 min read

Object-Oriented Programming in ColdFusion

Object-Oriented Programming in ColdFusion

Break free from procedural programming and learn how to optimize your applications and enhance your skills using objects and design patterns

  • Fast-paced easy-to-follow guide introducing object-oriented programming for ColdFusion developers
  • Enhance your applications by building structured applications utilizing basic design patterns and object-oriented principles
  • Streamline your code base with reusable, modular objects
  • Packed with example code and useful snippets

      

For those with any experience with ColdFusion, components should be relatively commonplace. Object-Oriented Programming (OOP) relies heavily on the use of ColdFusion components, so before proceeding onto the ins and outs of OOP, let’s re-familiarize ourselves with components within ColdFusion.

ColdFusion Components use the same ColdFusion Markup Language (CFML) as ‘standard’ ColdFusion pages. The core difference is the file extension—components must be saved with a .cfc file extension as opposed to the .cfm file extensions for template pages.

The basic structure of a ColdFusion Component is:

  • The component (the page within which you create the code to hold data or perform functions)
  • The methods available to run within the CFC, also known as functions

In simple terms, CFCs themselves form a framework within ColdFusion, allowing you to write structured, clear, and organized code. They make application development easier to manage, control, and maintain.

ColdFusion Components use the same CFML as ‘standard’ ColdFusion pages. The core difference is the file extension.

Why use CFCs?

It is not unusual for applications to grow and seem overly complex. Pages containing detailed information, such as business logic, data access and manipulation, data validation, and layout/presentation logic, can become untidy and hard to manage.

Creating and developing applications using CFCs enables you to separate the code logic from the design and presentation, and build an application based around, if not using, traditional Model View Controller (MVC) framework methodologies.

Utilizing CFCs and creating a clear structured format for your code will help reduce the complexity of logic within your pages and improve the application speed. Having a clearly structured, well organized code base will make it easier to develop as an individual and share resources within a team. This is the instant benefit of CFC development.

A well-written CFC will allow you to reuse your functions, or methods, across your entire application, helping to reduce the risk of code duplication. It will keep your component libraries and code base to a more easily manageable size, preventing it from becoming convoluted and difficult to follow.

ColdFusion components are an incredibly powerful and valuable means of creating efficient code. They allow you to:

  • Share properties and variables between other methods and functions
  • Share and interact with functions contained within other CFCs
  • Inherit the properties and methods of a base component
  • Overwrite methods and functions within other components

CFCs also give you the ability to clearly document and comment your code, letting you and other developers know what each function and property should do, what it should be expecting to receive to do the job and what output it will give you. ColdFusion components are able to read themselves and display this data to you, using a form of introspection.

Although CFCs are an effective tool for code reuse, this is not to say they should be used for every reusable function within your application. They are not a complete replacement for custom tags and user-defined functions.

When you load a CFC (instantiate the component), this uses up more processing time than it would to call a custom tag or a User-Defined Function (UDF) into use. Once a CFC has been instantiated, however, calling a method or function within the component will take approximately the same time as it would to call a UDF.

It is important, therefore, that CFCs should not necessarily be used as a complete replacement for any UDFs or custom tags that you have in your application. Any code you write can, of course, be optimized, and changes can be made as you learn new things, but UDFs and custom tags perform perfectly well. Using them as they are will help to keep any processing overheads on your application to a minimum.

Grouping your functions

You may have already written custom tags and user-defined functions that allow similar functionality and reusability, for example, a series of UDFs that interact with a shopping cart. By grouping your functions within specific components according to their use and purpose, you can successfully keep your code library organized and more efficient.

You can also further clean your code library by compiling or grouping multiple related components into a package, clearly named and stored in a directory within your application.

Organizing your components

A typical method for organizing your CFC library is to create a directory structure based on your company or domain name, followed by a directory whose name references the purpose of the included components, for example, ‘com.coldfumonkeh.projecttracker’ in the webroot of your application.

Within this directory, you would then create a directory for each group (or package), of components, with a name reflecting or matching the component name and purpose.

Object-Oriented Programming in ColdFusion

Use your ColdFusion Components to create a component structure, or a library, that contains grouped methods and functions, particularly if the methods share properties or data.

The ColdFusion component tags

You can use these following tags to create a ColdFusion Component.

TagPurposecfcomponentThe core CFC tag that defines the component structure. All other content in the component is wrapped within this tag.cffunctionCreates a method (function) within the component.cfargumentCreates a parameter, otherwise known as an argument, to be sent to the function.cfpropertyCan be used to define and document the properties within your component. Can also be used to define variables within a CFC that is used as a web service.

These previously mentioned tags are written within the .cfc file that defines the ColdFusion component.

In the world of object-oriented programming, you will commonly hear or see reference to the word ‘Class‘. A class is essentially a blueprint that is used to instantiate an object, and typically contains methods and instance variables.
When discussing a Class in the context of ColdFusion development, we are basically referencing a ColdFusion component, so when you see or read about classes, remember it is essentially an alias for a CFC.

Our first component

To get started, in this example, we will create a component and functions to output the message “Hello world”.

Create a new file called greetings.cfc and save it within your ColdFusion webroot.

The following is a component base tag; add this code into the new CFC to define the component:

<cfcomponent displayName=”greetings”>
</cfcomponent>


Listing 1.1 – component base tags

As you can see, the name attribute within the CFC matches the name of the file. The cfcomponent tags form the base structure of our ColdFusion Component. No other code can be placed outside of these tags, as it will simply display an error.

It may be helpful to think of the cfcomponent tag as the wrapping paper on a parcel. It forms the outer shell of the package, holding everything else nicely in place.

Defining a method

We have now created the component, but at the moment it does not actually do anything. It has no function to run. We need to add a method into the CFC to create a function to call and use within our application. The following code is a basic function definition; place it between the opening and closing cfcomponent tags:

<cffunction name=”sayHello”>
<!— the CFML code for the method will go here —>
</cffunction>


Listing 1.2 – basic function definition

You have now added a method to the CFC. The cffunction tags are nested within the cfcomponent tags. We now need to add some CFML code within the cffunction tags to create our method and perform the operation. Let’s create a variable within the function that will be our display message. The following code is for declaring a string variable; place it inside the cffunction tags:

<cffunction name=”sayHello”>
<cfset var strHelloMessage = ‘Hello World!’ />
</cffunction>


Listing 1.3 – declaring a string variable

We have created a string variable containing the text to display to the browser.

Returning the data

To return the data we need to add an extra tag into the method. This is possible by using the cfreturn tag, which returns results from a component method. The cfreturn tag has one required attribute that is the expression or value you wish to return.

Add the following code to your CFC so our method will return the welcome message and the completed component will look like this:

<cfcomponent displayName=”greetings”>
<cffunction name=”sayHello”>
<cfset var strHelloMessage = ‘Hello World!’ />
<cfreturn strHelloMessage />
</cffunction>
</cfcomponent>


Listing 1.4 – returning data from the function

ColdFusion 9 scripted components

Since the release of ColdFusion 9, developers now have the ability to also write ColdFusion components in complete script syntax instead of pure tag form.

To write the previous component in this format, the code would look as follows:

component
displayname=”greetings”
{
function sayHello(){
// the CFML code for the method will go here
var strHelloMessage=’Hello World’;
return strHelloMessage;
}
}


Listing 1.5 – component declaration in the script syntax

Although written using cfscript syntax, there is no requirement to wrap the code within <cfscript> tags, instead we can write it directly within the .cfc page.

We do not even need to contain the code within cfcomponent tags, as the entire content of the component will be compiled as cfscript if left as plain text without tags.

Creating your object

There it is, a simple ColdFusion Component. The method is created using the cffunction tags, wrapped up nicely within the cfcomponent tags, and the value returned using the cfreturn tag. Now that we have written the function, how do we call it?

In this example, we will call the component and run the method by using the createObject() function. Create a new file called hello.cfm and add the following code to the template:

<cfset objGreeting = createObject(‘component’, ‘greetings’) />
<cfoutput>#objGreeting.sayHello()#</cfoutput>


Listing 1.6 – creating the component object

In the previous code, we have created an instance of the greetings CFC, which we can reference by using the objGreeting variable. We have then accessed the sayHello() method within the component, surrounded by cfoutput tags, to display the returned data.

Save the file and view it within your browser. You should now see the welcome message that we created within the method.

Object-Oriented Programming in ColdFusion

Restricting your functions to scopes

Imagine we are sending some data through to a login page in our application within the URL scope; the first and last name of a particular person. On the page, we want to join the two values and combine them into one string to form the individual’s full name. We could write the code directly on the page, as follows:

<cfoutput>
Hello, #URL.firstName# #URL.lastName#
</cfoutput>


Listing 1.7 – displaying URL variables as a string

Although this works, you can revise the code and transform it into a ColdFusion function to concatenate the two values into the required single string and return that value:

<cffunction name=”getName”>
<cfset var strFullName = URL.firstName & ‘ ‘ & URL.lastName />
<cfreturn strFullName />
</cffunction>


Listing 1.8 – concatenate variables into string

You can then call this function within your .cfm page to output the resulting string from the function:

<cfoutput>
#getName()#
</cfoutput>


However, within this code you have restricted yourself to using only the specific URL scope. What if the first name and last name values were in the FORM scope, or pulled from a query? This block of code is useful only for values within the form scope.

Using arguments within your methods

To allow us to be able to pass in any parameters into the getName() function, we need to use the cfargument tag to send data into the method. By changing the function in the following code example, the method will create the concatenated string and produce the same results from two parameters or arguments that you choose to pass in.

<cffunction name=”getName”>
<cfargument name=”firstName” type=”string” />
<cfargument name=”lastName” type=”string” />
<cfset var strFullName = arguments.firstName & ‘
‘ & arguments.lastName />
<cfreturn strFullName />
</cffunction>


Listing 1.10 – using arguments within your function

The cfargument tag creates a parameter definition within the component method, and allows you to send in arguments for inclusion into the functions.

The Arguments scope

The Arguments scope only exists in a method. The scope contains any variables that you have passed into that method, and you can access the variables within the Arguments scope in the following ways:

  • using structure notation – Arguments.variablename or Arguments[“variablename”]
  • using array notation – Arguments[1]

The Arguments scope does not persist between calls to available CFC methods, meaning that you cannot access a value within the Arguments scope in one function from inside a different function.

Redefine the function parameters

By defining two arguments and sending in the values for the first and last names, you have created an unrestricted function that is not tied to a specific scope or set of hardcoded values. You can instead choose what values to pass into it on your calling page:

<cfoutput>
#getName(‘Gary’, ‘Brown’)#
</cfoutput>


Listing 1.11a – sending parameters into our function

Now that we have removed any restrictions to the values we pass in, and taken away any references to hardcoded variables, we can reuse this function, sending in whichever values or variables we choose to. For example, we could use variables from the FORM scope, URL scope, or query items to concatenate the string:

<cfoutput>
#getName(form.firstName, form.lastName)#
</cfoutput>


Listing 1.11b – sending parameters into our function

Let’s take our getName() method and add it into the greeting.cfc file. By doing so, we are grouping two methods that have a similarity in purpose into one component. This is good programming practice and will aid in creating manageable and clearly organized code.

Our greeting.cfc should now look like this:

<cfcomponent name=”greetings”>
<cffunction name=”sayHello”>
<cfset var strHelloMessage = ‘Hello World!’ />
<cfreturn strHelloMessage />
</cffunction>
<cffunction name=”getName”>
<cfargument name=”firstName” type=”string” />
<cfargument name=”lastName” type=”string” />
<cfset var strFullName = arguments.firstName & ‘
‘ & arguments.lastName />
<cfreturn strFullName />
</cffunction>
</cfcomponent>


Listing 1.12 – revised greeting.cfc

Combining your methods

As we have seen, you can easily access the methods within a defined CFC and output the data in a .cfm template page.

You can also easily access the functionality of one method in a CFC from another method. This is particularly useful when your component definition contains grouped functions that may have a relationship based upon their common purpose.

To show this, let’s create a new method that will use the results from both of our existing functions within the greetings.cfc file. Instead of displaying a generic “Hello World” message, we will incorporate the returned data from the getName() method and display a personalized greeting.

Create a new method within the CFC, called personalGreeting.

<cffunction name=”personalGreeting”>
<cfargument name=”firstName” type=”string” />
<cfargument name=”lastName” type=”string” />
<cfscript>
strHello = sayHello();
strFullName = getName(firstName=arguments.firstName,
lastName=arguments.lastName);
strHelloMessage = strHello & ‘ My name is ‘ & strFullName;
</cfscript>
<cfreturn strHelloMessage />
</cffunction>


Listing 1.13 – personalGreeting method

Within this method, we are calling our two previously defined methods. The returned value from the sayHello() method is being stored as a string variable, “strHello“.

We then retrieve the returned value from the getName() method and store this in a string variable “strFullName“. As we have written the getName() function to accept two arguments to form the concatenated name string, we also need to add the same two arguments to the personalGreeting() method , as done in the previous code. They will then be passed through to the getName() method in exactly the same way as if we were calling that function directly.

Using the two variables that now hold the returned data, we create our strHelloMessage variable, which joins the two values, and is then returned from the method using the cfreturn tag.

In this method, we used CFScript instead of CFML and cfset tags, which were used in our previous functions. There is no hard and fast rule for this. You can use whichever coding method you find the most comfortable.

Let’s call this method on our hello.cfm template page, using the following code:

<!— instatiate the component —>
<cfset objGreeting = createObject(‘component’, ‘greetings’) />
<!— access the method and assign results to a string —>
<cfset strPersonalGreeting = objGreeting.personalGreeting(
firstName=”Gary”, lastName=”Brown”) />
<cfoutput>#strPersonalGreeting#</cfoutput>


Listing 1.14 – calling the personalGreeting method

We are sending in the same arguments that we were passing through to the original getName() method, in the same way. This time we are passing these through using the newly created personalGreeting() method.

You should now see a personalized greeting message displayed in your browser:

Object-Oriented Programming in ColdFusion

LEAVE A REPLY

Please enter your comment!
Please enter your name here