Posts with the tag 'code'


observer design pattern in coldfusion

The observer design pattern is used in application development to observe the state of an object.  The best way to think about it is the publish / subscribe model.  In this pattern you have one object that is being observed (the subject), and a group of objects watching the subject called observers or listeners.  This pattern is an excellent example of loose coupling, because our classes can interact with very little knowledge of each other.

(read about the pattern @ http://en.wikipedia.org/wiki/Observer_pattern )

This post will demonstrate the usage of this pattern in ColdFusion

In the example I am creating a user list and the list if being watched by a logging observers that prints the message out to the browser anytime the new user gets added

IObservable.cfc
The Object that will provide notification to registered observers/listeners needs to implement this interface, in our case it will be UserList.cfc

  1. <cfinterface>
  2. <cffunction name="registerObserver">
  3. <cfargument name="observer" type="any">
  4. </cffunction>
  5.  
  6. <cffunction name="unregisterObserver">
  7. <cfargument name="observer" type="any">
  8. </cffunction>
  9.  
  10. <cffunction name="notifyObservers">
  11. <cfargument name="args" type="any">
  12. </cffunction>
  13. </cfinterface>

IObserver.cfc
The Object that will recieve notifications has to implement this interface, in our case it will be UserListLogger.cfc

  1. <cfinterface>
  2. <cffunction name="getInstanceID" returntype="String"/>
  3.  
  4. <cffunction name="onChanged">
  5. <cfargument name="sender" type="any">
  6. <cfargument name="args" type="any">
  7. </cffunction>
  8. </cfinterface>

UserList.cfc
This Class implements the IObservable interface

  1. <cfcomponent implements="IObservable">
  2. <cfscript>
  3. variables._observers = StructNew();
  4. </cfscript>
  5.  
  6. <cffunction name="addCustomer">
  7. <cfargument name="name">
  8. <!--- perform some action --->
  9. <cfset notifyObservers(arguments.name)>
  10. </cffunction>
  11.  
  12. <cffunction name="registerObserver">
  13. <cfargument name="observer" type="any">
  14. <cfif not StructKeyExists(variables._observers,arguments.observer.getInstanceID())>
  15. <cfset StructInsert(variables._observers, arguments.observer.getInstanceID(), arguments.observer)>
  16. </cfif>
  17.  
  18. </cffunction>
  19.  
  20. <cffunction name="unregisterObserver">
  21. <cfargument name="observer" type="any">
  22. <cfif StructKeyExists(variables._observers,arguments.observer.getInstanceID())>
  23. <cfset StructDelete(variables._observers, arguments.observer.getInstanceID())>
  24. </cfif>
  25. </cffunction>
  26.  
  27. <cffunction name="notifyObservers">
  28. <cfargument name="args">
  29. <cfloop collection="#variables._observers#" item="key">
  30. <cfset observer = StructFind(variables._observers, key)>
  31. <cfset observer.onChanged(this, arguments.args)>
  32. </cfloop>
  33. </cffunction>
  34. </cfcomponent>

UserListLogger.cfc
This Class implements the IObserver interface and at present only displays the information on browser

  1. <cfcomponent implements="IObserver">
  2. <cfset variables.instanceID = CreateUUID() >
  3.  
  4. <cffunction name="getInstanceID" returntype="String">
  5. <cfreturn variables.instanceID>
  6. </cffunction>
  7.  
  8. <cffunction name="onChanged">
  9. <cfargument name="sender" type="any">
  10. <cfargument name="args" type="any">
  11. <cfoutput><b>#arguments.args#</b> added to the user list<br></cfoutput>
  12. </cffunction>
  13. </cfcomponent>

test.cfm
The code here creates a UserList and registers the UserListLogger with it. The remaining part of the code adds user to the list and as soon the user is add, the UserListLogger gets notification of change.

  1. <cfset userList = CreateObject("component","UserList")>
  2. <cfset userList.registerObserver(CreateObject("component", "UserListLogger"))>
  3. <cfset userList.addCustomer( "Arjun" )>
  4. <cfset userList.addCustomer( "Vivaan" )>

The output of test.cfm will look like this


Arjun added to the user list
Vivaan added to the user list

Something worth watching is how the loose coupling of components, the UserList does not know what UserListLogger is doing or going to do with the notification. In fact there can be multiple listeners attached with UserList e.g. listeners to perform data base insert, listeners for email notification etc. The UserList does not care about how many or what type of listeners is attached to it, instead it just focuses on its task of notifying to the registered listeners about the change.
As you can see by following this pattern we can create ColdFusion applications that can adapt to changes and is easily maintainable.

Download Source Code

1 comment April 14th, 2008

Webservices AxisFault Handling in Coldfusion 8

Day was going fine, had my morning coffee attended project related meeting by the time I got back to check the mail I saw a chain of message going back and forth between the coldfusion developers and the backed web services developer regarding the AxisFault subject.

The issue started with the changes that backend/services team implemented in development environment, where they were throwing axis fault in error situation so that the calling application can trap that information and perform appropriate action, It was a little different then how it used to be down before. The main issue for the coldfusion developer was that they were not getting the AxisFault object back, instead in the exception object the fault data was back as a string which they parse and search for the error code and description.

After having the discussion with both the group it was clear that services team wanted to keep the functionality but for frontend/coldfusion team it was additional burden for parsing string and looking for information.

axis_4.JPG

frontend developers did not wanted to perform the find/search on the faultString or other exception properties, instead they were looking for coldfusion server to return them the exact AxisFault object.

After knowing the problem I googled for the solution to see if anybody have worked with AxisFault in coldfusion and nothing turned out, so to get frontend developers going I wrote a function that would reconstruct the AxisFault object from coldfusion exception so that they are spared from string search type work.

axis_5.JPG

Here is how the result of getAxisFaultDetail looks like
axis_2.JPG

Download code

This functionality was welcomed by the developers in my company I hope somebody out there might be looking for something similar, so here is the code that transactions faultString to AxisFault object

Add comment February 7th, 2008


 Subscribe in a RSS reader

Tags

Calendar

November 2008
M T W T F S S
« Jun    
 12
3456789
10111213141516
17181920212223
24252627282930

Posts by Month

Posts by Category