Sample use of the CF_Implements custom tag (this will be long)

8 Files used

IComparable.cfc

<cfcomponent>
	<cffunction name="getInstanceData" returntype="struct">
	
	</cffunction>
</cfcomponent>

INameable.cfc

<cfcomponent>
	<cffunction name="setName" access="private" returntype="void">
		<cfargument name="thename" type="string" required="yes">
	</cffunction>
</cfcomponent>

baseComparable.cfc - implements IComparable

<cfcomponent>
	<cfmodule template="implements.cfm" interfaces="franciswscott.cfimplements.icomparable" />
	<!--- or if copied to the custom tag directory
	<cf_implements interfaces="franciswscott.cfimplements.iComparable" />
	--->
	 
	<cffunction name="getInstanceData" returntype="struct" access="public">
		<cfreturn variables.instance />
	</cffunction>		
	
</cfcomponent>

person.cfc - Implements INameable - extends baseComparable

<cfcomponent extends="baseComparable">
	<cfmodule template="implements.cfm" interfaces="franciswscott.cfimplements.iNameable" />
	<!--- or if copied to the custom tag directory
	<cf_implements interfaces="franciswscott.cfimplements.iNameable" />
	--->
	
	<cfset variables.instance = structnew() />
	
	<cffunction name="setname" access="public" returntype="void">
		<cfargument name="myname" type="string" required="yes" />
		<cfset variables.instance.firstname = arguments.myname />
	</cffunction>
	
</cfcomponent>

dog.cfc - Implements INameable - extends baseComparable

<cfcomponent extends="franciswscott.cfimplements.baseComparable">
	<cfmodule template="implements.cfm" interfaces="franciswscott.cfimplements.inameable" />
	<!--- or if copied to the custom tag directory
	<cf_implements interfaces="franciswscott.cfimplements.iNameable" />
	--->
	
	<cfset variables.instance = structnew() />
	
	<cffunction name="setname" access="public" returntype="void">
		<cfargument name="myname" type="string" required="yes" />
		<cfset variables.instance.dogname = arguments.myname />
	</cffunction>

</cfcomponent>

compare.cfc - Accepts IComparable

<cfcomponent>
	<cffunction name="comparethese" access="public" returntype="boolean">
		<cfargument name="instance1" type="iComparable" required="yes">
		<cfargument name="instance2" type="iComparable" required="yes">		
		<cfreturn structCompare(arguments.instance1.getInstanceData(),arguments.instance2.getInstanceData()) />
	</cffunction>
	
<cfscript>
/**
 * Recursive functions to compare structures and arrays.
 * Fix by Jose Alfonso.
 * 
 * @param LeftStruct 	 The first struct. (Required)
 * @param RightStruct 	 The second structure. (Required)
 * @return Returns a boolean. 
 * @author Ja Carter (ja@nuorbit.com) 
 * @version 2, October 14, 2005 
 */
function structCompare(LeftStruct,RightStruct) {
	var result = true;
	var LeftStructKeys = "";
	var RightStructKeys = "";
	var key = "";
	
	//Make sure both params are structures
	if (NOT (isStruct(LeftStruct) AND isStruct(RightStruct))) return false;

	//Make sure both structures have the same keys
	LeftStructKeys = ListSort(StructKeyList(LeftStruct),"TextNoCase","ASC");
	RightStructKeys = ListSort(StructKeyList(RightStruct),"TextNoCase","ASC");
	if(LeftStructKeys neq RightStructKeys) return false;	
	
	// Loop through the keys and compare them one at a time
	for (key in LeftStruct) {
		//Key is a structure, call structCompare()
		if (isStruct(LeftStruct[key])){
			result = structCompare(LeftStruct[key],RightStruct[key]);
			if (NOT result) return false;
		//Key is an array, call arrayCompare()
		} else if (isArray(LeftStruct[key])){
			result = arrayCompare(LeftStruct[key],RightStruct[key]);
			if (NOT result) return false;
		// A simple type comparison here
		} else {
			if(LeftStruct[key] IS NOT RightStruct[key]) return false;
		}
	}
	return true;
}
</cfscript>
	
</cfcomponent>

namesetter.cfc - Accepts INameable

<cfcomponent>
	<cffunction name="setName" access="public" returntype="void">
		<cfargument name="instance" type="iNameable" required="yes">
		<cfargument name="setto" type="string" required="yes">		
		<cfset arguments.instance.setName(arguments.setto) />

	</cffunction>
</cfcomponent>

index.cfm

<cfset dog = createobject("component","dog") />

<cfset person = createobject("component","person") />
<cfset comparer = createObject("component","compare") />
<cfset namesetter = createObject("component","namesetter") />
<cfdump var="#comparer.comparethese(person,dog)#" />
<cfset namesetter.setName(person,'Scotty') />
<cfset namesetter.setName(dog,'Bob') />
<br />
<cfdump var="#comparer.comparethese(person,dog)#" />

We get the following results after running this

true
false