The CFUnited 2009 Topics Survey is now open, you can go there and vote for your favorite topics you'd like to see presented.

I have re-submitted my topic (you can find it under the "Please choose 4 from the list of topics that cover OO" section) from last year as it was well received and attended, and I'm hoping to make this year's presentation even better, so please head on over to the survey and voice your opinion and hopefully vote for my as well. I promise you won't be disappointed.

Leveraging Basic Object Oriented Concepts and Design Patterns in ColdFusion - Phill Nacelli

This session will introduce you to the basic concepts of object oriented development along with some basic design patterns by looking at real world code examples. Today's ColdFusion developers are bombarded by complex terms such as Singletons, Facades, Data Access Objects(DAOs) and other design patterns, making it hard for the novice to understand these valuable concepts without looking at actual code. This session will demystify those terms and give you the basic knowledge needed to build a foundation into the real advantages of Object Oriented programming.

As promised, here are the slides and code examples for my CF.Objective() 2008 presentation. Feel free to post any comments or questions and I'll get to them asap.

As I mentioned after the presentation, I'm also going to be putting together an intermediate version of this talk covering more complex patterns. Also, I have been told that CF.Objective() 2009 will be tentatively scheduled for May 6-9. So now you have plenty of time to begin schmoozing your bosses to let you go. I have to say that this is THE conference for learning the high level skills needed to build enterprise level applications in ColdFusion.


Here's the link to download the presentation and code examples:

Leveraging_Basic_Design_Patterns_in_ColdFusion

Come work with us!

AboutWeb, LLC has an exciting opportunity for an Object-Oriented ColdFusion Developer to join our Solutions Team in Rockville. Selected new team member should have a solid background in ColdFusion MX 7/8 and experience with the following:

  • Demonstrated experience developing Object-Oriented applications.
  • Experience with MVC or 3-tier Architecture.
  • CSS, Custom Tags.
  • Production level development in Java, .NET, Flex or Ajax will be considered pluses.
  • CF Certification, or willingness to obtain certification.
  • Current Clearance or ability to pass background investigation.

If you are interested, we would like to talk to you soon! Please email your resume to jarchy[at]aboutweb[dot]com.

Doug Hughes on Service Layer

For a while now, I've been planning on blogging on this same subject, however Doug Hughes beat me to the punch and did a great job making a case for using Service Layers in your applications, which I agree with wholeheartedly. Kudos Doug!

You can read his entry here: Put Your Controllers on a Diet, Use a Service Layer by Doug Hughes

ObjectFactory Explained

In my previous post, I posted some code from the CentralPA CFUG presentation that Scott Stroz and I used. It used an ObjectFactory.cfc file that I had created prior to the presentation and am kicking myself for not doing/using this earlier. Now you're probably saying to yourself... "Another ObjectFactory!!!". Yes, this one I hope will prove to have its uses.

First, a bit about objectFactories. In a nutshell, objectFactories are nothing more then an object that returns other objects given a key. Meaning once objectFactory is instantiated in the application (in our case in the Application scope as a singleton), I can simply get to any objects "known" within the objectFactory by calling it like this:

Listing 1
<cfset myObjectInstance = application.objectFactory.create("ObjectKey") />

One of the advantages to this approach is obvious, there's no need to defined the entire path to the object everytime I need to instantiate it. This comes very handy if I have to make changes to my object paths, for example while using a proxy object to wrap the original object (see Decorator Pattern). When using an objectFactory, all my object paths are all in one place and not scattered throughout my entire application. Here's an example of a regular objectFactory:

Listing 2 - ObjectFactory.cfc
<cfcomponent displayname="ObjectFactory">

<!--- constructor method --->
<cffunction name="init" access="public" returntype="ObjectFactory" output="false" hint="constructor method">
<cfreturn this />
</cffunction>

<!--- public methods --->
<cffunction name="create" access="public" returntype="Any" output="false" hint="I return an object">
<cfargument name="objectKey" type="String" required="yes" />
<cfset var object = 0 />
<cfswitch expression="#arguments.objectKey#">
<cfcase value="Registrant">
<cfset object = createObject("component","cfugDemo.com.model.registrant.Registrant") />
</cfcase>
<cfcase value="RegistrantGateway">
    <cfset object = createObject("component","cfugDemo.com.model.registrant.RegistrantGateway") />
</cfcase>
<cfcase value="Fee">
<cfset object = createObject("component","cfugDemo.com.model.fee.Fee") />
</cfcase>
<cfcase value="FeeGateway">
<cfset object = createObject("component","cfugDemo.com.model.fee.FeeGateway") />
</cfcase>
</cfswitch>
</cffunction>

</cfcomponent>

And this could be instantiated in my application as:

Listing 3 - Application.cfm
...

<!--- objectFactory - singleton --->
<cfif NOT structKeyExists(application,"objectFactory") OR url.reInit>
<cfset application.objectFactory = createObject("component","cfugDemo.com.model.objectFactory.ObjectFactory").init() />
</cfif>

...

And anytime I want to use an instance of an object I simply call it like this:

Listing 4
<!--- instantiate registrant --->
<cfset registrant = application.objectFactory.create("Registrant").init() />

As you can see the create method simply returns the appropriate object. So if I need to change the path to use a proxy object or an object that extends the object type already in my code I simply edit the ObjectFactory.cfc file.

Okay, that was a basic example of objectFactory, now why implement object oriented principles and still have to edit the ObjectFactory.cfc file everytime I want it to be able to return a new object. Isn't the reason we like CFC's because we can reuse them across our applications? Hence the improvements I made to the ObjectFactory.cfc. First, why hard code all objects in my application in the cfswitch statement if I can simply tell the ObjectFactory.cfc what objects are there on application start? By allowing me to register each object information once into my factory and store it into a Struct data type, it now can be reused and also the create method can run faster without the need to figure out which object to instantiate via the cfswitch.

Another improvement made was to be able to tell the ObjectFactory in the register method that an object is a singleton, meaning I only want that object instantiated once in my entire application and shared everytime it's requested. This is very useful for objects like DAO's, Gateways, and Config Beans. Since in ColdFusion complex objects are passed by reference, the ObjectFactory simply stores a reference to the instantiated object before it returns the object to the user. Since ObjectFactory is already being persisted in the Application scope, the singleton object is also persisted. So let's take a look at the new improved Object Factory below:

Listing 5 - ObjectFactory.cfc
<cfcomponent displayname="ObjectFactory" hint="ObjectFactory - Class Factory Object">

<!--- properties --->
<cfset variables.objectRegistry = 0 />
<cfset variables.applicationSingletons = 0 />

<!--- constructor init() method --->
<cffunction name="init" access="public" returntype="ObjectFactory" output="false" hint="initiates instance of ObjectFactory">
<cfset setObjectRegistry(structNew()) />
<cfset setSingletons(structNew()) />
<cfreturn this />
</cffunction>

<!--- getters/setters accessors methods --->
<cffunction name="getObjectRegistry" access="private" returntype="Struct" output="false" hint="gets objectRegistry property">
<cfreturn variables.objectRegistry />
</cffunction>
<cffunction name="setObjectRegistry" access="private" returntype="Void" output="false" hint="sets objectRegistry property">
<cfargument name="objectRegistry" type="Struct" required="yes" hint="value of objectRegistry" />
<cfset variables.objectRegistry = arguments.objectRegistry />
</cffunction>

<cffunction name="getSingletons" access="private" returntype="Struct" output="false" hint="gets singletons property">
<cfreturn variables.singletons />
</cffunction>
<cffunction name="setSingletons" access="private" returntype="Void" output="false" hint="sets singletons property">
<cfargument name="singletons" type="Struct" required="yes" hint="value of singletons" />
<cfset variables.singletons = arguments.singletons />
</cffunction>

<!--- public methods --->
<cffunction name="register" access="public" returntype="Void" output="false" hint="registers object information into factory">
<cfargument name="key" type="String" required="yes" hint />
<cfargument name="object" type="String" required="yes" />
<cfargument name="isSingleton" type="Boolean" required="no" default="false" />
<cfargument name="type" type="String" required="no" default="Component" />
<!--- init local var(s) --->
<cfset var registerComponent = getObjectRegistry() />
<!--- register component info --->
<cfset registerComponent[arguments.key] = structNew() />
<cfset registerComponent[arguments.key].object = arguments.object />
<cfset registerComponent[arguments.key].isSingleton = arguments.isSingleton />
<cfset registerComponent[arguments.key].type = arguments.type />
</cffunction>

<cffunction name="unregister" access="public" returntype="Void" output="false" hint="unregisters object information from factory">
<cfargument name="key" type="String" required="yes" />
<!--- if object is registered, remove it from registry --->
<cfif structKeyExists(getObjectRegistry(),arguments.key)>
<cfset structDelete(getObjectRegistry(),arguments.key) />
</cfif>
</cffunction>

<cffunction name="create" access="public" returntype="Any" output="false" hint="returns instantiated object">
<cfargument name="key" type="String" required="yes" />
<!--- init local var(s) --->
<cfset var objectRegistry = getObjectRegistry() />
<cfset var singletons = getSingletons() />
<cfset var registeredObject = 0 />
<cfset var object = 0 />
<!--- check if object is in objectRegistry --->
<cfif structKeyExists(objectRegistry,arguments.key)>
<cfset registeredObject = objectRegistry[arguments.key] />
<!--- if object was flagged as singleton and has already been instantiated get object from singleton struct --->
<cfif registeredObject.isSingleton AND structKeyExists(singletons,arguments.key)>
<cfset object = singletons[arguments.key] />
<cfelse>
<!--- instantiate new object to return --->
<cfset object = createObject("#registeredObject.type#","#registeredObject.object#") />
<!--- if new object is to be instantiated as a singleton add instance reference to applicationSingletons struct --->
<cfif registeredObject.isSingleton>
<cfset singletons[arguments.key] = object />
</cfif>
</cfif>
<cfelse>
<!--- return false if key does not exist in objectRegistry --->
<cfset object = false />
</cfif>
<cfreturn object />
</cffunction>

</cfcomponent>

Notice that once I instantiate the object (see Listing 4) I can then register each object into it:

Listing 6 - Application.cfm
...

<!--- register objects --->
<cfif NOT structKeyExists(application,"objectFactory") OR url.reInit>
<!--- registrant --->
<cfset application.objectFactory.register("Registrant","cfugdemo.com.model.registrant.Registrant") />
<cfset application.objectFactory.register("RegistrantGateway","cfugdemo.com.model.registrant.RegistrantGateway",true) />
<!--- fee --->
<cfset application.objectFactory.register("Fee","cfugdemo.com.model.fee.Fee") />
<cfset application.objectFactory.register("FeeGateway","cfugdemo.com.model.fee.FeeGateway",true) />
</cfif>

...

For those objects I want to be instantiated as singletons like RegistrantGateway and FeeGateway notice the third optional argument is set to true. Also, in this case we are registering all objects explicitly in code, you could also read an xml file with objects definition info in it and loop through the content and register them automatically. As you can see this ObjectFactory can now be reused in any of my applications without having to make application specific changes to it, it's also a bit faster in that it doesn't have to do any loop or switch statements to find the object to instantiate it (this would really be significant in applications with many objects but worth mentioning).

Central PA CFUG Preso Recap

Thanks for those that were able to make to last night's ColdFusion and Object Oriented Programming II talk at the Central PA CFUG meeting. Specially those that drove through the storm and flooded streets!

I'll be posting the presentation slides along with the code later on today. Also stay tuned for the recorded Breeze/Connecto(urgh!) presentation once we have the url.

If you have any questions about the presentation or anything we covered, please feel free to post a comment here and I'll promise to answer asap.

Download the presentation sample oo code here or in the "Download" button below.

View the presentation here.

CF8-Scorpio: Image Manipulation

So I'm here in Rockville,MD doing my best to follow MAX 2006 from a distance, keeping an eye on blogs, Adobe.com, labs.adobe.com, etc...

One of the things that I'm excited about is the announcement that CF8, codenamed Scorpio, will have built in image manipulation tags. However, after looking at some of the examples on how it works, I wish that the syntax would follow a more object like approach.

For example, here you create a new image to be manipulated, say we're resizing it, using the default CF8 way:

<!--- create image --->
<cfset myImage = imageNew("foo.jpg") />

<!--- resize image - imageResize(image,width,height) --->
<cfset imageResize(myImage,"50%","50%") />

Instead, wouldn't it be nice to be able to do:
<!--- create image --->
<cfset myImage = imageNew("foo.jpg") />

<!--- resize image - imageResize(image,width,height) --->
<cfset myImage.resize("50%","50%") />

Changing the subject a bit:
Now, I know that for years we have done the same thing with Array, Struct data types. I feel the same about them as I do about the image manipulation feature. If we treat Arrays, Structs, and Images as "data types" in a more Object-Oriented manner, my opinion is that it will help CF users become more aware of Object Oriented concepts, than if we just give them a set of methods to do a particular set of functionality. "CF is not an Object-Oriented language!", I totally agree, however, if we are to market ColdFusion as an enterprise level application platform, we need to start following some sort of proven development methodologies that attract decision makers, Object-Oriented concepts have been proven in ColdFusion with the creation of CFCs, however the number of CFML developers in our community that are ready to take on such projects are lacking.

Object-Oriented Programming in ColdFusion Presentation

Just a quick note that I'll be presenting for the Central Pennsylvania ColdFusion User's Group with Nic Tunney on "Using Object-Oriented Programming in ColdFusion". This will be a basic overview of OO, advantages over procedural coding, and how ColdFusion can take advantage of some of these concepts.

It will take place on Thursday, October 19th at 7:00pm at Country Meadows of Hershey. Looking forward to meeting you there.

cfOOP - ColdFusion Object-Oriented Programming site is now live

Nic Tunney has just launched another great site, cfOOP.org. This site is totally devoted to Object-Oriented programming in ColdFusion.

At Nic's request, I'll be writing an article on creating your typical Address Book organizer online application. The article will cover the planning phases of the application to building a simple app, then being able to upgrade the application to support more complex concepts to later integrating it into an MVC/Object-Oriented framework gradually. This upgrades will hopefully show the readers the many advantages of using OO, specially maintainability and flexibility to grow.

BlogCFC was created by Raymond Camden. This blog is running version 5.003. Powered by ColdFusion Server v8,0,1,195765.