Following on from my previous post on a ColdFusion implementation of the Head First Design Patterns web MVC Pattern is a ColdFusion implementation of the Strategy Pattern.
The Strategy Pattern is probably the most useful pattern, to quote the Head First book:
"The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it."
Abstract Duck
Duck.cfc
<cfcomponent output="true">
<cffunction access="public" returntype="void" name="display">
</cffunction>
<cffunction access="public" returntype="void" name="performFly">
<cfset VARIABLES.flyBehaviour.fly()>
</cffunction>
<cffunction access="public" returntype="void" name="performQuack">
<cfset VARIABLES.quackBehaviour.quack()>
</cffunction>
<cffunction access="public" returntype="void" name="swim">
<cfoutput>All ducks float, even decoys!<br/></cfoutput>
</cffunction>
<cffunction access="public" returntype="void" name="setFlyBehaviour">
<cfargument required="true" type="FlyBehaviour" name="flyBehaviour">
<cfset VARIABLES.flyBehaviour = ARGUMENTS.flyBehaviour>
</cffunction>
<cffunction access="public" returntype="void" name="setQuackBehaviour">
<cfargument required="true" type="QuackBehaviour" name="quackBehaviour">
<cfset VARIABLES.quackBehaviour = ARGUMENTS.quackBehaviour>
</cffunction>
</cfcomponent>
Quack Strategies
Quack.cfc
<cfcomponent implements="QuackBehaviour" output="true">
<cffunction access="public" returntype="Quack" name="init">
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="quack">
<cfoutput>Quack<br/></cfoutput>
</cffunction>
</cfcomponent>
Fly Strategies
FlyWithWings.cfc
<cfcomponent implements="FlyBehaviour" output="true">
<cffunction access="public" returntype="FlyWithWings" name="init">
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="fly">
<cfoutput>I'm flying!<br/></cfoutput>
</cffunction>
</cfcomponent>
FlyNoWay.cfc
<cfcomponent implements="FlyBehaviour" output="true">
<cffunction access="public" returntype="FlyNoWay" name="init">
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="fly">
<cfoutput>I can't fly<br/></cfoutput>
</cffunction>
</cfcomponent>
FlyRocketPowered.cfc
<cfcomponent implements="FlyBehaviour" output="true">
<cffunction access="public" returntype="FlyRocketPowered" name="init">
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="fly">
<cfoutput>I'm flying with a rocket!<br/></cfoutput>
</cffunction>
</cfcomponent>
Duck Implementations
MallardDuck.cfc
<cfcomponent extends="Duck" output="true">
<cffunction access="public" returntype="MallardDuck" name="init">
<cfset VARIABLES.flyBehaviour = createObject("component", "FlyWithWings").init()>
<cfset VARIABLES.quackBehaviour = createObject("component", "Quack").init()>
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="display">
<cfoutput>I'm a real Mallard duck<br/></cfoutput>
</cffunction>
</cfcomponent>
ModelDuck.cfc
<cfcomponent extends="Duck" output="true">
<cffunction access="public" returntype="ModelDuck" name="init">
<cfset VARIABLES.flyBehaviour = createObject("component", "FlyNoWay").init()>
<cfset VARIABLES.quackBehaviour = createObject("component", "Quack").init()>
<cfreturn THIS>
</cffunction>
<cffunction access="public" returntype="void" name="display">
<cfoutput>I'm a model duck<br/></cfoutput>
</cffunction>
</cfcomponent>
Test Page
MiniDuckSimulator.cfm
<cfset mallard = createObject("component", "MallardDuck").init()>
<cfset mallard.performQuack()>
<cfset mallard.performFly()>
<cfset model = createObject("component", "ModelDuck").init()>
<cfset model.performFly()>
<cfset model.setFlyBehaviour(createObject("component", "FlyRocketPowered").init())>
<cfset model.performFly()>
Source Code
- Head First Strategy ColdFusion Builder Project - headfirststrategy.zip