Tuesday 16 February 2010

ColdFusion Head First Design Patterns: MVC

Head First Design Patterns is a pretty good book, with loads of good code examples in Java and not nearly as dry as GoF. It's even got a fit bird on the front cover. Careful though, looks like she's rocking an itchy twunt.

Source code for the book is available here.

For this post I've taken the web application MVC code written in Java/Servlets/JSP and re-coded it in CFML.

Model

BeatModel.cfc

<cfcomponent output="false">

  <cfset VARIABLES.bpm = 90>

  <cffunction returntype="BeatModel" name="init">
    <cfreturn this>
  </cffunction>

  <cffunction returntype="void" name="on">
    <cfset setBPM(90)>
  </cffunction>

  <cffunction returntype="void" name="off">
    <cfset setBPM(0)>
  </cffunction>

  <cffunction returntype="void" name="setBPM">
    <cfargument required="yes" type="numeric" name="bpm" />

    <cfset VARIABLES.bpm = ARGUMENTS.bpm>
  </cffunction>

  <cffunction returntype="numeric" name="getBPM">
    <cfreturn VARIABLES.bpm>
  </cffunction>
  
</cfcomponent>

View

DJView.cfm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <title>DJ View</title>
  </head>
 <body>
    <h1>DJ View</h1> 
    Beats per minute = <cfoutput>#APPLICATION.beatModel.getBPM()#</cfoutput>    
    <br />
    <hr />
    <br />    
    <form method="post" action="DJView.cfc">
      BPM: <input type="text" name="bpm" value="<cfoutput>#APPLICATION.beatModel.getBPM()#</cfoutput>" />
       
      <input type="submit" name="set" value="set" />
      <br />
      <input type="submit" name="decrease" value="<<" />
      <input type="submit" name="increase" value=">>" />
      <br />
      <input type="submit" name="on" value="on" />
      <input type="submit" name="off" value="off" />
    </form>
  </body>  
</html>

Controller

DJView.cfc

<cfcomponent output="false">

  <cfif NOT isDefined("FORM.bpm")>
    <cfset FORM.bpm = APPLICATION.beatModel.getBPM()>
  </cfif>
  
  <cfif isDefined("FORM.set")>
    <cfset APPLICATION.beatModel.setBPM(trim(FORM.bpm))>
  </cfif>
  
  <cfif isDefined("FORM.decrease")>
    <cfset APPLICATION.beatModel.setBPM(APPLICATION.beatModel.getBPM() - 1)>
  </cfif>
 
  <cfif isDefined("FORM.increase")>
    <cfset APPLICATION.beatModel.setBPM(APPLICATION.beatModel.getBPM() + 1)>
  </cfif>
 
  <cfif isDefined("FORM.on")>
    <cfset APPLICATION.beatModel.on()>
  </cfif>

  <cfif isDefined("FORM.off")>
    <cfset APPLICATION.beatModel.off()>
  </cfif>

  <cflocation url="DJView.cfm">

</cfcomponent>

Initialization

Application.cfc

<cfcomponent output="false">

  <cfset THIS.Name = "Head First MVC" />
   
  <cffunction access="public" returntype="void" name="onApplicationStart">
    <cfset APPLICATION.beatModel = createObject("component", "BeatModel").init()>
  </cffunction>
  
</cfcomponent>

Source Code