Fusebox is a fantastic framework that offers tremendous flexibility and functionality. I’ll discuss various concepts that make Fusebox code easier to create, maintain, and reuse. I’ll use ColdFusion examples, but these concepts are compatible with any language’s implementation of the Fusebox framework.
Are you new to the Fusebox technology? Learn more with these articles.
Every developer I know has had the horrible experience of opening up someone else’s code and discovering no comments. You can kiss a chunk of time goodbye as you attempt to wade through the code to figure out the functionality. And if you have to change or add to the code, it would be nice to know if the change will affect any dependent files. We all know we’re supposed to comment our code, but what, exactly, are we supposed to comment on? Different developers have different styles of commenting, which can add to the confusion. Too often, commenting is an afterthought, something rushed through once the code is written.
When the Fusebox 3 framework was released, the specification for Fusedoc 2 was also made available. Fusedocs are a set of structured comments used to describe a code file. They’re written in XML, with a document type definition (DTD) available. If you happen to use ColdFusion Studio as your editor, there’s a VTML toolkit available that greatly speeds up the act of writing Fusedocs.
Fusedocs are extremely useful because they provide a standard, detailed, and organized description for a code file, which is a “fuse” in Fusebox terminology. The Fusedoc describes the purpose of the fuse, what data the fuse requires to operate, what data the fuse is required to produce, a change history, and more.
Listing A contains a Fusedoc for a simple login page. The <io> section is the most important. This “input/output” section defines what data is required by the fuse and what data it must produce or pass on. In this case, the fuse is expecting a variable called xfa.submitForm (I’ll talk more about XFAs in the second half of this article). The fuse must produce two variables, username and password. The actual code for the fuse described by this Fusedoc could be written as Listing B.
The next step in our application flow is checking the username and password against a database of users to see if the user’s credentials are entered correctly. The Fusedoc for this template is in Listing C, and the code for this fuse is in Listing D.
The final step in the login process is establishing session information for the user, assuming the username and password were entered correctly. Afterwards, the user is directed to the site’s main page. Otherwise the user will be sent back to the login page to try again. Listing E contains the Fusedoc for this code file, and Listing F shows the code.
Clearly there are benefits to laying out a fuse’s responsibilities in such a structured and detailed way. It might look like a lot of typing, but the VTML tools simplify the process. And because the Fusedocs are in XML, they can be read or parsed in numerous ways. One exciting possibility is to automate testing by having another application read the Fusedoc, provide the specified variables, and determine if the required data is produced.
Fusedocs also help immensely during code maintenance. A new developer can open up your fuse and, by reading the Fusedoc, tell immediately what it’s doing and what resources it relies upon to function. Fusedocs also act as a “change history”—when modifications are made to the fuse, the Fusedoc is updated to explain what was altered.
I’ve saved the next idea for last because it often contradicts the “normal” process of development. Nearly all comments are written after the code is written. Fusedocs are written before the code is written. The application architect writes Fusedocs for all the fuses during the architecture phase. By doing this much detailed planning up front, many kinks and problems are exposed early. Changing the Fusedocs is much easier and cheaper than changing code after it is written.
Prewritten Fusedocs make development much more smooth and defined. The coder is given a sort of “contract” (the Fusedoc) that clearly lays out what the code must do. If the code fulfills the requirements defined in the Fusedoc, the coder is finished with that fuse. This makes distributed and team environments more efficient. In fact, if the Fusedoc is written correctly, it could be handed to a competent developer who could write that fuse with no knowledge of the rest of the application or its underlying database or databases.
An important note about Fusedocs is they don’t describe implementation details, only what the incoming and outgoing data must be. It’s up to the developer to determine the optimum way to fill the requirements set forth in the Fusedoc.
Exit fuseactions (XFAs)
A core component of the Fusebox framework is the exit fuseaction (XFA). This powerful feature is a request handler that is passed or defined on each call to a Fusebox application. Fuseactions almost always represent public methods.
For example, a Fusebox application’s home page might have a newsletter sign-up form. The URL in the sign-up form might looks like this:
In this example, the fuseaction is a hard-coded value, “newsletter.processSignupForm.” If for some reason we wanted to change this, or we were reusing this code and wanted it to do something different, we’d have to open up the actual fuse file and alter it manually. A more manageable solution, especially if code reuse is a goal (and it should be), is to make the fuseactions themselves dynamic values.
I mean using a variable for the fuseaction. So the link in our home page display fuse would become:
We set this variable in our FBX_Switch file. The FBX_Switch file is one of the core files of the Fusebox framework. Full details are available in my previous article, “Fusebox 3 improves on its predecessor.” In summary, the FBX_Switch file accepts the fuseaction request handler and, based on the fuseaction, executes the appropriate code to fulfill the request. Here’s a portion of an FBX_Switch.cfm file:
XFAs represent any of the “exit points” of a fuse, meaning any actions causing a new request to the application. These could be links, forms, or HTTP redirects. By using variables as our fuseactions and setting the variables in our FBX_Switch file, we gain several big advantages.
The first advantage is that the FBX_Switch file becomes a better “map” of our application. Just looking at the different CFCASE values and the XFAs that are set instantly shows what actions a fuse is capable of performing. By looking at the CFCASE above, you can tell pretty quickly that the dsp_HomePage file has 3 exit points: viewing a list of products, displaying a contact form, and processing a newsletter sign-up form.
The second benefit is easier code reuse and maintenance. Suppose I decide that when the user submits the newsletter signup form, I don’t want to go straight to processing the form, but instead want to show the user a list of other newsletters that I think might be of interest before I process the signup. Instead of having to go into the dsp_HomePage.cfm fuse file and edit it, I can just alter the XFA setting to:
This is a very simplistic example, and the full power of XFAs takes a little time to get your head around, but once you understand their use, I guarantee that you’ll never go back to hard-coded fuseactions.
A third benefit of using XFAs is that it places the burden of determining application flow on the application architect instead of the developer. This way, the developer doesn’t have to worry about what comes next, or how this code file needs to interact with the rest of the application. They simply use the XFAs described in the Fusedoc and move on.
The fourth advantage of XFAs is a little more complex. Because the fuseactions themselves are dynamic, you can use conditional logic to determine on the fly what a given fuseaction will do. By altering the value of your XFA variable, you can, at runtime, change the actions that your application is capable of performing.
I hope these examples of Fusedocs and XFAs convey the advantages of Fusebox development.