ColdFusion MX and Fusebox
By Michael Smith
TeraTech, Inc
Fusebox is a
popular development methodology for ColdFusion. I gave it a test drive on
ColdFusion MX to see how it faired and to look for new possibilities with the
new features in ColdFusion MX such as CFCs and functions.
Overview
What is a
methodology? A methodology organizes your project and code for better
communication, documentation and maintenance.
In my mind what the
Fusebox methodology (www.fusebox.org)
does best is showing non-programmers (of whom there are many who develop in CF)
a standard, structured way of getting things done in an easy and methodical
way. Any methodology would work in that respect, however Fusebox (probably
because of the great community that supports it and its long history) seems to
be the most popular one for CF. Also the methodology itself has been ported and
used in ASP, JSP and PHP as well.
The biggest
benefits are not technical. Rather they
result from the standardization of coding practices, everyone speaks the same
language, and everyone can read the same code and understand it. It makes for easier transitions with and for
programmers. A programmer who knows
Fusebox going into a Fusebox shop is going to be a lot more productive much
more quickly because they don't need to learn how that shop does its
architecture. Both sides benefit.
Key features of
Fusebox include:
·
Splitting code
into small fuses by type (HTML, SQL, CF) helps organize programs for better
maintenance.
- Having all the flow control one place
(fbx_switch.cfm) makes the site’s page flow self-documenting.
·
Softcoding
fuse exit points with XFAs in the fbx_switch.cfm file makes moving code between
apps for reuse easier
·
Nested layouts
are good for working with designers as their files mainly contain HTML and
don’t have complex CFML code to confuse them.
·
XML format
Fusedocs improve program communication and allow for auto test page generation.
Fusebox Lifecycle Process
Fusebox covers both
the project lifecycle and actual coding. The Fusebox Lifecycle Process (FLiP)
consists of wireframing, HTML prototyping and Devnote signoff. It attacks the
fundamental problem of most projects -- WIBINWYCAW – “What Is Built Is Not What
Your Client Actually Wanted” (as opposed to what they originally said they
wanted!).
The first step in
FLiP is wireframing -- a way to layout all the pages and links in a site in a
way that the client can click through a working wireframe model of the site. No
colors or graphics are done at this stage – we just focus on what the pages
must do and the flow between pages. There are several wireframe tools written
in ColdFusion and I tested out the one written by Lee Borkman
(Bjork.net). After some tweaks for new
reserved words in ColdFusion MX such as equals, it ran fine in ColdFusion MX
and let me quickly create a wireframe outline of my test site.
The next step in
FLiP is to create an HTML prototype of the pages. Obviously pure HTML runs just
fine in ColdFusion MX, so this step was no problem. We ended up with an exact
visual model of the site – with correct colors, graphics and layout but no
functionality other than the links and buttons go to the correct pages. This
may seem like trouble to write, but would you rather write pure HTML and get feedback
now, or write CFML and have to rewrite it again and again?
We save these HTML
prototype files with CFM extensions so we can add the next piece of the Fusebox
puzzle – Devnotes. These are little user notes that appear at the bottom of
each prototype page that the user can add comments to. They are used to
communicate changes to the pages in writing from the client to the developer.
The Devnotes code is called from OnRequestEnd.cfm, which is called at the end
of each page request. For OnRequestEnd to work we need a corresponding
Application.cfm to be run at the page beginning (it can be a single blank line)
After a review with
the end users of the program and some changes suggested by them the client did
a formal sign-off on the prototype pages. From this point on we know exactly
what the site will look like – no graphics or layout changes are allowed until after delivery. In fact by tying down
the layout we have also specified much of the database and functionality
requirements – it is not possible to add a new field, for example, without
changing the layout…
Now we are ready to start architecting the application. We
printout the prototype screens and mark them up brainstorming exit points,
fuseactions and circuits. From that information, a Mind Map is created,
allowing us to visualize the application. But the Mind Map is not a dead-end.
UsingFuseminder (www.grokfusebox.com),
we create the application skeleton from the Mind Map. Hundreds of lines of code
are written for us. Write the Fusedocs, and your fuses are ready for coding.
By using FLiP
applications are less buggy, developed faster, and clients are happier because
you delivered what they asked for.
Framework, flow control and nested inheritance
Now we are ready to
code! We have a hierarchy of circuit directories and a list of fuseactions for
each circuit. First lets start with the Fusebox framework files:
fbx_fusebox30_CFXX.cfm, fbx_settings.cfm, fbx_switch.cfm fbx_circuits.cfm and
fbx_layouts.cfm.
The Fusebox core
file fbx_fusebox30_CFXX.cfm provides the brains behind the Fusebox framework. I
tested with the CF50 file but I expect there will be a CF60 version available
from www.fusebox.org that is optimized for
ColdFusion MX by the time you read this article. The version 5 code seemed to
run fine in ColdFusion MX, allaying my compatibility worries. I did have to
change the test in index.cfm for the version in
server.coldfusion.productVersion to allow versions greater than 5, but that was
all.
The
fbx_settings.cfm file contains circuit-wide settings such as security and
constants such as request.dsn. The fbx_settings.cfm files are nested, starting
at the root, one inside another down to the target circuit. This way,
inheritance is provided to nested circuits, so that child circuits can override
parent values.
The fbx_switch.cfm
decides which fuses to call to accomplish the requested fuseaction. It is
basically a CFSWITCH statement on the fuseaction variable with one or more
CFLINCLUDEs to fuse files that
dothe actual work; the display
(dsp_*.cfm), CFML actions (act_*.cfm) or SQL queries (qry_*.cfm). The resulting
HTML is captured using CFSAVECONTENT by the Fusebox core file. It is then
displayed by the layout file specified in this circuits fbx_layouts.cfm
file. This helps separate graphical layout from code. The resulting HTML is
passed back up through the parent circuits providing for nest layout of menu
options. Similarly as errors are caught
by the fbx_errorCatch.cfm file
and may be optionally bubbled up through the parent circuits to the root
circuit.
Finally the core
file outputs the completed nested layout. Layouts may also be selected based on
user interaction or personalization settings. A simple fbx_switch.cfm is shown
below.
<cfswitch
expression = "#fusebox.fuseaction#">
<cfcase
value="showInputForm">
<cfset XFA.add =
"admin.add">
<cfset XFA.edit =
"admin.edit">
<cfset XFA.delete =
"admin.delete">
<cfinclude
template="dsp_InputForm.cfm">
</cfcase>
<cfcase
value="showEmployeeList">
<cfinclude
template="qry_EmployeeList.cfm>
<cfinclude
template="dsp_EmployeeList.cfm>
</cfcase>
<cfdefaultcase>
<cfoutput>I received a fuseaction
called #fusebox.fuseaction#" that
circuit "#fusebox.circuit#"
doesn't have a handler for.</cfoutput>
</cfdefaultcase>
</cfswitch>
Fuse division of labor
The fuses are where
the work of a Fusebox application is done. We have already seen the Fusebox
framework files – they all have the prefix fbx_. The other fuses start with
dsp_, lay_, act_ or qry_ to separate out the display, layout, CFML and SQL
parts of the code.
Display fuses (dsp_
prefix) and Layout fuses (lay_ prefix) are the only fuses that can
present output to the client. Some CFML tags such as CFOUTPUT and sometimes
CFIF are allowed, but the idea is to restrict these fuses to mainly HTML. This
allows graphics and
Web designers to edit them more easily than typical CF heavy files. Note
the display may be in regular HTML for a browser, or WML for a WAP phone, or XML
for a web service. In the latter cases Fusebox does not add any white space to
your output, which saves many headaches with web services.
Action fuses (act_ prefix) on the other hand only contain CFML and
cannot display output. They however may assemble data for display into
variables that are used in later dsp_ files. This focus on CFML by action fuses
eases debugging and reusability.
Query fuses (qry_ prefix) also can not display output, but
unlike action fuses they are for SQL queries and other record set producing
tags such as CFDIRECTORY. In addition to the query tag they might also use
CFPARAM and CFQUERYPARM to validate their arguments but no other CFML
processing. Keeping all the queries in one file type makes it easy to hand off
SQL to a DBA for optimization
or conversion to stored procedures. In fact some Fuseboxers use
a fake query generating tag called CF_QuerySim(www.halhelms.com) to
generate result sets even before the database design is complete!
We want fuses to be code “black boxes” that we can use
without having to open them up to modify code for reuse. One way we improve
reuse is by replacing all hardcoded exit points by variables called Exit Fuse
Actions (XFAs). This way the exit point can be defined in the fbx_switch.cfm
file and the fuse “rewired” from the outside if it is moved to another
application. Compare this to traditional CF coding practice where to reuse code you often have to edit all the
code to change the URLs, Form submit and other exit points to the new directory
structure. Additionally it documents the exits points in the switch file so
that all flow control is visible
there.
Note that XFA are
usually given names like XFA.success and in ColdFusion MX these automatically
become a structure XFA instead of just being a variable called “XFA.success” as
they would be in earlier versions of ColdFusion. This didn’t seem to cause any
problems with using them and could come in handy if you wanted to loop over all
available XFAs.
What happens when
you do need to go into the
black box of a fuse? How will you know what it does – the answer is the
XML formatted Fusedocs. Similar to
Javadocs, these notes give
developers a standard way to communicate what a fuse does, the change history
and what input/output it handles.
Plus as they are in a format that is easily read by programs, they can be used by automatic documentation and test
generation tools. By specify modules in detail before coding fewer bugs are
produced.
The future of Fusebox
The new features in
ColdFusion MX such as CFC components and full functions let us improve Fusebox
more. One possibility is to move the fuseactions for a circuit into a CFC as
public methods. The fuses could then be private methods in that CFC. There are
several potential problems with this idea. Firstly instead of having all the
code available for editing by multiple developers it is now all in one file.
This makes giving all the HTML to a designer and all the SQL to the DBA harder.
Additionally finding the fuse
of a given name is now no longer a case of just finding the fuse name in the
file window. Fortunately I
understand that the new code editor Dreamweaver MX may have a method browser
similar to the one in Visual Basic.
Another issue to
resolve is the fact that currently fuses all run in the same variable scope due
to the use of CFINCLUDEs. Methods
in a CFC keep their variables private, so either all variables will need to be passed explicitly, or put
in the request scope so that they are available to all fuses in the page
request..
Both ColdFusion MX
and Fusebox bring some aspects of object-oriented design to ColdFusion
programming. Similarly some of the ideas from the java world such as javadocs
have influenced Fusebox. I expect more ideas to come over from java, in
particular there has been some interested in the Model-View-Controller (MVC) model by the godfather of Fusebox
Hal Helms (see article http://halhelms.com/writings/MVC.htm)
Model circuits,
especially, would seem ideally suited for the object-based nature of CFCs.
Summary
In conclusion
Fusebox is a helpful methodology for programming in ColdFusion MX and gains new
power with this new release of ColdFusion. Fusebox separates flow control,
display, action and query code into modular files for easier maintenance.
Soft-coded exit points and XML formatted documentation aid code reuse. The
Fusebox Lifecycle methods of wireframing, prototyping, devnotes and formal
signoff ensure your client gets want they really want.
Bio
Michael Smith is president of TeraTech http://www.teratech.com/
, a 13-year-old Rockville, Maryland based consulting company that specializes
in ColdFusion, Database and Visual Basic development. TeraTech uses the Fusebox
development methodology. Michael runs the MDCFUG and recently organized the
two-day, Washington, DC-based CFUN conference that attracted more than 700
participants. You can reach Michael at [email protected] or 301-881-1440.