Instantiation
In object orientation, there are 2 terms you will see used a lot. One is class, and the other is object. Sometimes they seem to be interchangeable. But there is an important concept to grasp here.
When we code a CFC, what we have is really a blueprint, a class in object oriented terms. So essentially, the word class refers more to the blueprint that you write in code.
So for this example, let's create a CFC and call it Person.cfc
<cffunction name="init" access="public" output="false">
<cfargument name="Name" type="string" required="true">
<cfset setName(arguments.Name)/>
<cfreturn this />
</cffunction>
<cffunction name="setName" access="private" output="false">
<cfargument name="Name" type="string" required="true">
<cfset variables.Name = arguments.Name />
</cffunction>
<cffunction name="getName" returntype="string" output="false">
<cfreturn variables.Name />
</cffunction>
</cfcomponent>
You can see clearly when looking at this particular code sample that it is just a blueprint, in other words a class. A person has a name, but in our code, no specific name is set. We could create representations of many different people with this code block and set their individual names differently.
So in ColdFusion, when we use the CreateObject() function (or the cfobject tag), and in many cases assign a variable to the object we create so we can refer to it later in our code, we are creating an instance of the class Person. Let's do that.
<cfset InstanceOfPersonCalledTom.init('Tom')>
So the above code block is an example of instantiation. Instantiation implies usually 2 things, creating an instance of a CFC, and doing the necessary to prepare that instance for use. In our simple example, we used the init() function to set Tom's name.
Essentially, it's similar to using the StructNew() function to create a structure and then populate it with data. With a structure, you assign a variable name to the new structure so you can use it, and then you set the necessary values in the keys.
<cfset person.name = "Tom" />
Let's take a closer look at our Person CFC. Remember that in OO speak, people would refer to this as a class.
<cffunction name="init" access="public" output="false">
<cfargument name="Name" type="string" required="true">
<cfset setName(arguments.Name)/>
<cfreturn this />
</cffunction>
<cffunction name="setName" access="private" output="false">
<cfargument name="Name" type="string" required="true">
<cfset variables.Name = arguments.Name />
</cffunction>
<cffunction name="getName" returntype="string" output="false">
<cfreturn variables.Name />
</cffunction>
</cfcomponent>
By convention in ColdFusion, the init() function is where you prepare your CFC for use, and as we said before, this is often implied in the term instantiate. You will also sometimes find the word initialize used to describe this step. In this simple example, it doesn't make much sense to have a Person without a name. So the init() function has a required argument for the name of the person, and it's specified that it should be a string.
What this shows me as a developer working on a project, just by looking at the code, is that you should always pass in a name when you instantiate a Person. We could have just created the object and used the setName() function instead to pass the name into the CFC ... but then it wouldn't be indicated clearly in our blueprint that setting the name should be part of the instantiation of the object.
You'll also notice that the setName() function is private, meaning that this method can only be accessed from within the object. This makes it "impossible" to change an InstanceOfPersonCalledTom's name to Fred. We've determined, as a "business rule", that it shouldn't happen that the name of a person changes in our simple example application. So building our blueprint with setName() private indicates that to other developer working on our project. Once the name is set at instantiation, it shouldn't change.
We could have also not bothered including a setName() function and just made the init() method in our blueprint like this:
<cfargument name="Name" type="string" required="true">
<cfset variables.Name = arguments.Name />
<cfreturn this />
</cffunction>
At first glance to the writer of the blueprint, that might seem more simple and clear. But if another developer comes along and sees it (or you look at your own code in a few months!), they (or you!) could interpret this in 2 ways. One is that the author of the code was being lazy and didn't write a setter for Name. Or they also might conclude that excluding the setter meant that setting the Name should happen at instantiation.
But if the init() function calls a private setName() method as below:
<cfargument name="Name" required="true">
<cfset setName(arguments.Name)/>
<cfreturn this />
</cffunction>
<cffunction name="setName" access="private" output="false">
<cfargument name="Name" required="true">
<cfset variables.Name = arguments.Name />
</cffunction>
then our blueprint is unambiguously clear.
You'll also find going along that more experienced OO programmers always use setters and getters in their objects. Even tho' that often adds more code to your blueprint, there are good reasons for that.
If you look closely at the init function, you'll see that besides accepting an argument called "Name" and using the setName() function to set the name in the variables scope of our Person instance, it also returns "this".
In a CFC, "this" has a special meaning. It means the whole CFC instance - all the methods and data within it are contained in the variable "this".
Returning "this" in the init() method allows you to do what is called "method chaining". So instead of
<cfset InstanceOfPersonCalledMary.init('Mary')>
You can do
... which instantiates your object in one line of code, which many programmers find a little clearer. As pointed out in the comments below, instantiating your object in one line of code like that in cases where your object is instantiated into a persistent scope is important because it makes it "thread safe".
You'll find example code returning "this" in the init() method in many cases.
So to review, when you instantiate a CFC, which would be called a class in object-speak, what you get is an instance, an object that you can use in your code. A class is like a blueprint, and you can instantiate many object instances from a class.
The term instantiate also implies preparing your object for use. And depending on what that object's responsibilities are, it could simply include setting a few simple values, or running a series of complex calculations from several functions that utilize the capabilities of other objects and setting the results in a variety of other objects.
So we've answered a few questions, but a reader new to CFC's and object orientation will have more questions from the above arising in their mind. For instance:
If a structure is so simple to use, i see just 2 lines of code up there, why should we bother with all the complication of objects? What advantage do they have over a simple, easy to understand struct?
And what's this "passing" term mean? You said you "passed" a name into the init() function. Why can't you just set it in the request scope? That way you could forget about the init() function, and the setName() function, and just have a getName() function that simply returns request.tomsName. In fact, in this case, you don't even need the whole Person object. You can reference request.tomsName from anywhere in the app. So again, if using the request scope is so easy, why bother with using a complicated CFC?
And you know, there's another thing. I hear people talk about getters and setters all the time on the lists, and i see a getName() and setName() method here. Isn't there a simpler way to set a variable in these things?
And i don't get this line:
What does that do? Why use the variables scope?
So it looks like we have a few more questions to answer in the coming days about the bare bones basics of using CFC's in an object oriented manner in ColdFusion. A few more might even show up in the comments!


One small comment (stolen from Sean's factories presentation): CreateObject("component","Person").init('Mary') is not just subjectively neater, it's objectively preferable for reasons of thread safety.
Jaime
Thanks for the comment. We'll have to go over what thread safety means in some later post for anyone who isn't familiar with the term, but can you expand on that a bit? I'm not sure i understand how separating CreateObject() and an init() call can create a thread safety issue.
without the method chaining, you have this line of code:
1. <cfset foo = createObject('component', 'Person') />
it exists, but has not yet been initialized. so you add the following line:
2. <cfset foo.init('Mary') />
now your CFC has been created and properly initialized. w00t!
but... what happens if, in between lines 1 and 2, another thread/process makes a call to foo? in theory, it's been created...so it can be called. but it has not yet been initialized. so while it exists, it doesn't exist in a "ready state".
it's a small window...but on a heavily trafficked application, it's not inconceivable to think that in between creation and initialization that another process might try and access the newly-created object.
method chaining the init() just makes sure that in one swell foop the object is created and initialized, thus eliminating (or at the very least, significantly reducing) the possibility of that happening.
(btw, i should state for the record that this is my understanding... but i'm still at the "Helen Keller at the OO waterfountain" stage of the game... so hopefully i got that right and don't further confuse the issue)
Nevertheless, that still makes method chaining your init() a best practice for me.
Which reminds me that we should cover double locking when instantiating objects into persistent scopes!
And you used the "initialized" word, so that should also go in the text here as a synonym of "instantiated", just to make it clear.
yeah, that makes sense that it would only be an issue if the object was created into a memory-resident scope.
i'm confused tho about your saying the terms "initialized" and "instantiated" are synonymous. to me, they're not (at least in this case). in fact, in this situation that we've been discussing, i take instantiated to mean created (via the createObject() method) and initialized to mean that the init() method has been called and run successfully and the component is not "ready" for use.
are they synonymous in a more general OO-speak kinda way?
In my experience people use the terminology in different ways. I guess all i'm saying here is that to use an object, you've got to create an instance of one and often get it in a state where it's ready to be used ... and you'll see people using these terms to refer to that process (instantiate, instantiation, initialize ...) and Charlie says that he thinks the term "initialize" only refers to the process that gets an object ready for use ... and he's probably right. But someone might use initialize to refer to the whole process anyway.
Even i get confused by all the terms if i'm not careful to distinguish between the meaning of them sometimes.
To expand on the scoping, normally you won't worry about this type of thing on the page output. But, if you are working within a CFC as you have listed above, you definitely want to specify which scope the variable is going to end up in (as you have done). If, for example, you posted your name in the this scope, you could set the name w/o using the setter.
e.g. instanceOfPersonCalledMary.name = "bob";
This (the above) is a good example of why/when *not* to use the this scope since you are circumventing your business logic. Conversely, in your example of the this scope, it is a perfect example of when to use it. There are of course edge cases where you will want to be able to have this functionality. But that's a different discussion.
Further, another good thing to point out while on the topic of scopes and concurrency, is queries within CFCs. In my experience many people will forget to set their query to the var scope prior to running them (see example below). This can cause some _very_ hard to debug problems, i.e. I'm getting someone elses' shopping cart and I have no idea why. In the example you'll see that I set the variable in the this scope prior to running the query. This will ensure that my request, stays my request and someone else wont receive my cart contents.
<cffunction name="getCart" access="public" returntype="query" output="false">
<cfargument name="userID" type="numeric" required="yes" />
<cfset var theQuery = 0 />
<cfquery datasource="#dsn#" name="theQuery">
SELECT * FROM cart WHERE user_ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.userID#">
</cfquery>
<cfreturn theQuery />
</cffunction>