Wizards and Controllers — who needs a magic wand?

Now I will be the first to admit that I am still a beginner when it comes to the Force.com platform, and some of the smart optimizations that take place behind the scenes. I was excited when I came across one such example the other day when I was working with a client, where we implemented a pretty complex wizard. So far in my time with Salesforce.com, I have built a number of wizards where I relied on the cookbook to get me through, but this time I needed something with more kick.

Within the wizard we implemented, there can be a number of alternate flows depending on particular values of previously entered fields. I decided to implement the Wizard Controller as an extension, so I could inherit the standard controller functionality from the primary object I was interacting with, which happened to be an Account Application. As the wizard was going to have a lot of things it needed to handle, I encapsulated the flow logic into a series of classes implemented using the Chain of Responsibility pattern.

One of the methods in my Chain interface was called isFlow(). isFlow() checked a series of fields in the primary object to determine whether a particular course of action should be taken and certain screens rendered.

Everything was working great until we noticed when a user returned to wizard later, via the breadcrumbs we implemented, the fields being checked in isFlow() were null on pages that didn't have a apex component bound to the field.

After scratching my head for a while, I realized that what I was seeing was an intelligent optimization by the platform to only return the fields I was currently referencing on the page. Even though I was using my own custom controller, I was still relying on the standard controller to handle all of the magic of data retrieval for the primary object of my wizard.

So with the addition of an apex:inputHidden component, bound to the fields my wizard flow required, I was off and running, without the need to write another line of code.