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