-
Notifications
You must be signed in to change notification settings - Fork 24
CFC Primer Part 5: Using the Person CFC
By Matt Woodward (matt at mach-ii.com)
Let's assume we have a CFML template and we want to create an instance of the Person CFC, set the firstName
, lastName
, and birthdate
attributes, and then display these value of these attributes on the screen.
First, we instantiate the CFC by using the createObject()
function in CFML. There are numerous ways to instantiate CFCs, but the most frequently used method for instantiating CFCs in OO applications is createObject()
.
The createObject()
function takes two arguments: first, the object type, which in this case will be "component" since a CFC is being created; and second, the type of CFC to be instantiated, which in this case is "Person". Note that the ".cfc" extension is not added to the end of the CFC type argument to the createObject()
function.
Remember that an init()
method within the CFC was created to act as a constructor. After we call createObject()
, the init()
method on the object will be immediately called. Since the init()
method returns the object itself, a fully instantiated Person CFC will be created.
<cfset bob = CreateObject("component", "Person").init() />
We now have a variable bob
that is of type Person
, but the values of firstName
, lastName
, and birthdate
are set to their default values, because we did not pass these values into the init()
method when it was called. The correct values for the bob
object can be set in different ways. After instantiating the object, the setter methods can be called individually to set the data:
<cfset bob.setFirstName("Bob") />
<cfset bob.setLastName("Dylan") />
<cfset bob.setBirthdate("5/24/1941") />
Another way that the data can be set is to pass the values directly to the init()
constructor method in the order in which the arguments are declared within the init()
method:
<cfset bob = CreateObject("component", "Person").init("Bob", "Dylan", "5/24/1941") />
With the values for the bob
object's attributes set, they may now be output on the screen by calling the getter methods of the Person CFC:
<cfoutput>#bob.getFirstName()# #bob.getLastName()# was born on #bob.getBirthdate()#</cfoutput>
In the two examples above, individual setter methods were called to set the values of the attributes in the bob
instance of the Person
CFC.
Another method illustrated was to pass all the values to the init()
method in the order in which the arguments are declared within the init()
method. In some cases it may be inconvenient or impossible to pass data to the constructor or other methods in this way. For example, some arguments may be required and other arguments may be optional, and it may not be possible to use them as ordered arguments.
Fortunately, other ways exist for passing data to methods. One method is to pass arguments to the constructor as explicit name-value pairs. This method is useful for passing certain arguments to the constructor but omitting others, and this eliminates the reliance upon the order in which the arguments are declared within the init()
method. For example, let's create a Person object for the singer Madonna, who has only a first name and a birthdate.
In this case, init("Madonna", "8/16/1958")
cannot be called because this would set Madonna's last name to "8/16/1958" since in this case we are passing the arguments to the init()
method in order. This would not throw an error because the setLastName()
method would accept this date string as a string, but the state of the data within the object would not be correct.
By explicitly specifying name-value pairs, a developer can tell the init()
method exactly what it is receiving, and the order of the arguments no longer matters:
<cfset madonna = CreateObject("component", "Person").init(firstName = "Madonna", birthdate = "8/16/1958") />
Another method for passing data to a function is to use a structure with named keys. When using this method, note that the key names of the structure must match the name of the init()
method's arguments. In the Madonna example, a struct can be built with the data, and then this struct can be passed to the init()
method as a single argument collection:
<cfset madonnaData = StructNew() />
<cfset madonnaData.firstName = "Madonna" />
<cfset madonnaData.birthdate = "8/16/1958" />
<cfset madonna = CreateObject("component", "Person").init(argumentcollection = madonnaData) />
These four methods of passing arguments to functions give developers a great deal of flexibility regardless of the order in which the arguments are declared, and regardless of whether or not the arguments are required.
For many CFML developers, using CFCs may appear to be extra work. In addition, CFML developers with a procedural background will need to learn new approaches and techniques. The long-term payoff, however, is well worth the effort for the following reasons:
-
First and foremost, every modern programming language involves OO features, and today nearly all software is built using object-oriented programming techniques. It is rare for developers to build purely procedural applications. This is not surprising, considering that OO development has existed since the late 1960s. Although OOP is not a new concept, it is relatively new in the CFML world, and it is imperative that CFML developers embrace and learn OOP to be competitive with developers who use other technologies.
-
Second, CFCs provide developers a better way to build applications. Developers can build flexible, maintainable, and robust applications that are easy to test and debug by working with software objects as they exist in the real world. It may take additional effort for CFML developers more accustomed to older-style CFML coding to internalize these techniques, but most CFML developers who have made the switch cannot even imagine developing applications in any other way.
-
Finally, since CFCs are used for a host of other purposes within CFML, understanding CFCs is vital for taking full advantage of the following features in CFML:
- Web Services
- Flex (AMF) Integration
- AJAX Integration
- Event Gateways
With the addition of CFCs to the CFML language, CFML developers can now build fully object-oriented applications that are modularized, flexible, and easier to test, debug, and maintain. The encapsulation of related attributes (data) and behavior (methods) within a single component is a simple but powerful concept resulting in safer applications that are easy to extend. By providing the foundation for modeling real-world objects as software components, CFCs also give developers the opportunity to be more expressive and to create larger and more complex applications.