Welcome!

ColdFusion Authors: Maureen O'Gara, Hovhannes Avoyan, Yakov Fain, Pat Romanski, Liz McMillan

Related Topics: ColdFusion, Adobe Flex

ColdFusion: Article

ColdFusion Feature — Objects Everywhere

A solution to object-oriented spaghetti code

Since we are developers, we like to see code. What would a factory object look like?

<cfcomponent>
   <cffunction name="getCar" access="public" returntype="com.myDomain.Car">
     <cfargument name="make" type="string" required="true">

     <cfswitch expression="#arguments.make#">
       <cfcase value="corvette">
         <!--- create corvette object dependent objects --->
         <!--- create and return corvette car object --->
       </cfcase>
       <cfcase value="xlr">
         <!--- create cadillac xlr object dependent objects --->
         <!--- create and return cadillac xlr car object --->
       </cfcase>
     </cfswitch>

   </cffunction>
</cfcomponent>

Now, anytime I need to create a new Corvette, I just ask my factory for one like this:

<cfset oCorvette = oCarFactory.getCar('corvette') />

This is much, much better. Now, we have one place for all instantiation code instead of having it spread throughout the application. If we ever need to change the path of a component or add a new dependency, we just have to make the change in the factory. However...

You had to say it, didn't you? If you look at the code for our car factory and look into the future a bit, you will see that really, what we have done is move the spaghetti code from our application into the factory object. The code within that factory object is going to get quite complex, as for each type of car we create, we have to know all of the dependencies that that type of car has. Some of these dependencies will more than likely be shared by multiple types of cars as well, which means if the instantiation of an engine changes, we'll have to find all of the instances of that code in our factory and update them. While this is better than nothing, there is still room for improvement.

The Smart Object Factory
Along the way, some very smart people have taken the concept of the object factory and expanded upon it. Here enters the term Dependency Injection. What if, instead of building a huge switch statement inside of my factory, my factory was smart enough to handle all of the dependencies itself? For example, what if I could define for the factory a blueprint that says when you build an instance of a Car object, it is dependent upon instances of an Engine object and a Transmission object. At this point, my only concern is the Car object, not how to build the Engine or Transmission object. Later on in the plans, I define that when the factory builds an instance of an Engine, it is dependent upon an instance of a Cylinder object.

What have I done here? By separating the logic of building the Engine object away from the logic of building the Car object, I have encapsulated that logic. Now, if a Truck object also depends upon the Engine object, it can use the same set of blueprints that the Car object uses. This means if I have to change the way the Engine object is instantiated, I can do it in one place and let the factory handle putting all of the pieces together.

This sounds a whole lot more complicated than our little factory component. Never fear, somebody else has already done all of the heavy lifting for us. A framework has been developed called ColdSpring by Chris Scott and Dave Ross. The purpose of the ColdSpring framework is to "make the configuration and dependencies of CFCs easier to manage." Sounds exactly like what we are looking for. Let's look at some of the high-level help that ColdSpring can provide our application:

  • ColdSpring moves all component paths outside of the application code.
  • ColdSpring allows you to move or change implementations using single changes in XML.
  • ColdSpring handles all object initialization.
  • ColdSpring handles all object dependencies.
This almost sounds too good to be true. Let's take a quick look at the XML "blueprint" that we provide ColdSpring with in order for it to build our objects.

<bean id="Car" class="com.myDomain.Car">
    <constructor-arg name="Engine">
       <ref bean="Engine" />
    </constructor-arg>
    <constructor-arg name="Transmission">
       <ref bean="Transmission" />
    </constructor-arg>
</bean>

<bean id="Engine" class="com.myDomain.Engine" />
<bean id="Transmission" class="com.myDomain.Transmission" />

As you can see, we have specified a bean (object) definition for our Car object. The class (object path) is provided as well as a series of constructor arguments. This means, when ColdSpring creates a new instance of the Car object, it must also pass all of the listed arguments into that Car object's constructor method. In this case, the arguments include an instance of the Engine bean and the Transmission bean. Later on in the file, we find the bean definitions for the Engine and Transmission beans.

By utilizing ColdSpring and its XML blueprint, we have significantly cut the amount of code necessary to create new objects. Even within our factory, we no longer have to know all of the details of the dependent objects when we are defining a given object.

Conclusion
While object-oriented programming offers a wide array of benefits, it is still possible to write bad OO code just as you can write bad procedural code. An object factory is one of many good practices that, when added to your bag of tricks, can help cure the object explosion that tends to happen in many OO applications.

If you would like to find out more about some of the topics we only had room to briefly touch on here, check out the following resources.

• Freeman, E.; Freeman, E.; Sierra, K.; and Bates, B. (2004). Design Patterns - Head First Design Patterns. O'Reilly: www.oreilly.com/catalog/hfdesignpat/
• Corfield, S. "Managing ColdFusion Components with Factories": http://corfield.org/articles/cfobj_factories.pdf
• ColdSpring Framework (Chris Scott and Dave Ross) www.coldspringframework.org/

More Stories By Jeff Chastain

Jeff Chastain has been developing software applications using object-oriented programming for over 12 years and has been developing Web applications in ColdFusion for over 8 years. He has experience in a variety of industries, from Fortune 500 companies to his own consulting practice. Currently, Jeff is an applications architect and systems developer for Alagad, Inc., and contributes to the blog at http://www.doughughes.net.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.