Switching DAO Method Calls Based Upon CFC Type
Posted on Nov 20, 2008
Recently I encountered a situation whereby my services API had a requirement for a single method that actually retrieved many types of items, all of which extended an object that, for example purposes, I will call just "item." The biggest obstacle was that for various reasons, nothing inside the item told you what subtype it was (which is arguably a better solution than the one provided here). Nonetheless, there was a simple solution since the object itself can tell me what type it is just by examining the metadata, and I was able to call the appropriate methods using that information. Below I have the code that allows you to do this in case you encounter a similar requirement. This example does a read based upon the CFC type, but the same can be done for create, update and delete (or whatever else really).
<cffunction name="getItem" access="public" output="false" returntype="com.stuff.item">
<cfargument name="item" type="com.stuff.item" required="true" />
<cfset var cfcType = listLast(getMetadata(arguments.item).name,".") />
<cfswitch expression="#cfcType#">
<cfcase value="specificItem">
<cfset variables.specificItemDAO.read(argument.item) />
</cfcase>
<cfcase value="anotherItem">
<cfset variables.anotherItemDAO.read(argument.item) />
</cfcase>
<cfdefaultcase>
<cfthrow errorcode="com.stuff.itemService.itemTypeNotKnown" detail="You have passed an unregistered item type" />
</cfdefaultcase>
</cfswitch>
<cfreturn arguments.item />
</cffunction>
Comments
In the example, you're passing in the object and looks like you're retrieving the same one. What part am I missing?
That said, I'm more interested in the design decisions that led to this Gatekeeper of AllObjects. =)
Posted By Sammy Larbi / Posted on 11/20/2008 at 11:56 AM
@Sammi --
Yeah, but he's then passing the object to the read() method of a DAO before returning it. So when it comes out, it's properties are populated.
Posted By Tony Garcia / Posted on 11/20/2008 at 1:12 PM
In that case, I think a name like getItemByWhateverFieldsArePrePopulated() or populateMostlyEmptyItem() might aid in understanding what's going on.
How does it know what item to get if the item is not itself?
Posted By Sammy Larbi / Posted on 12/01/2008 at 9:46 AM
@sammy - In my dao the read populates an item based upon its id. The reason I ended up going with the "gatekeeper" as you call it is because the requirement I was given was for a *single method* to get an asset, but an asset could be one of many subtypes, so the only way to get any sub-type of asset was to determine which type you were trying to populate. Does that make sense?
Posted By Brian Rinaldi / Posted on 12/01/2008 at 9:53 AM
Yes, that aids my understanding. Thanks Brian.
Posted By Sammy Larbi / Posted on 12/01/2008 at 11:13 AM