| By Jeff Chastain | Article Rating: |
|
| May 15, 2007 06:15 PM EDT | Reads: |
13,004 |
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.
<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/
Published May 15, 2007 Reads 13,004
Copyright © 2007 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
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.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe Fiddles with its Web Apps
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF






















