By Peter Bell

The Future of Controllers: A Blast from the Past

Whether you use Fusebox, Mach-II, Model-Glue or your own home brewed framework, the chances are that you use a front controller (a single file – usually index.cfm – for processing all of your page requests). Ever since the early days of Fusebox this has been the best practice aspired to by most ColdFusion developers. It has been a while since I’ve heard a top CF developer selling the praises of the humble page controller.

I noticed this prejudice myself when doing a quick review of a site for a VC. I pointed out that while a page controller approach can work, there has historically been a pretty good correlation in the CF world between page controllers and junky code. Tonight I decided to take a step back to try to highlight the relative strengths of the old page controller. I haven’t written an app using a page controller since 1998 and I tend to dislike the approach, but it is sometimes important to stand up for the ideas you DON’T believe in. Then you can do a better job of explaining exactly how and where those ideas are and aren’t optimal.

Java’s Siren Song
Ever since I first saw the J2EE enterprise patterns page, I knew I was in love! So many patterns, so carefully crafted. One of the things I always felt was that the Java community got enterprise patterns in a way that the Microsoft world never did. I’ve posted a number of times in the past what I dislike about .NET, and most of it is to do with what I consider a set of fairly poor architectural approaches that developing in Visual Studio tends to encourage.

Given this and the fact that I’d got into the habit of using a front controller a long time ago, it was only recently that I stopped to ask: “what is wrong with a page controller”?! Of course, we all know that most design patterns have their place, but when was the last time you seriously considered using a page controller for an application (I know a bunch of people still do, which is cool). If not, why exactly did you eliminate it from the running?

It Don’t Get No Respect
The reason that I usually groan when I see a page controller is that most of the time mixed in with the controller logic are database calls and display logic. It’s the PHP syndrome where you assume that you can’t write maintainable code in PHP only because most people who code in PHP don’t know how to write maintainable code!

I was looking to see this old pattern with new eyes, so I cranked open my Patterns of Enterprise Architecture to page 333 to see what Martin Fowler had to say.

He was actually quite positive about the pattern for simple sites and noted that if you used helper classes for common controller functions (say handling of URL and form scopes and authentication) and ensure clear separation of concerns with clean model calls and separate view templates, you can actually create quite well structured applications with a page controller. In general a page controller works best when navigational complexity is lower.

On balance I still prefer the power of the front controller and like the fact that you can more easily use cfc’s for your controller logic which I find more natural now than putting it into cfm scripts. The truth is though that many applications I see being built using a front controller could have been implemented equally well using a page controller. I don’t see any compelling benefits to changing wholesale to what is a slightly less flexible pattern, but I was definitely surprised by how good an application you could build using a page controller if you decided to do so. It made me wonder what else I took for granted might not be exactly as I had assumed.

Comments
I too love the front controller. I think it makes for a cleaner, easier to maintain site. However, one thing that is nice about a page controller is that it's really the only true plug-and-play page. You can create a stand alone page and it just works. Nothing else in your application needs to know about it; no config files have to be updated; no controllers need to be updated; no master switch cases need additions. You can just make a "super_secret_page.htm", throw it up on the server, link to it, and viola! Page works like a charm.

Now, I am not saying anything about maintainability or scalability or anything. Certainly this is a nightmare for larger sites... but the beauty of it is ease of individual deployment.

Also, while I use the front controller as much as possible, it should be noteworthy that most of the pages that the front controller includes are, in essence, page controllers. Yes, my framework is doing extra work and what not as it builds the page, but the difference between a page controller and my individual action modules is not that huge. It's better, don't get me wrong, but clearly from the same family.
# Posted By Ben Nadel | 11/28/06 7:29 AM
Yeah, I've noticed the same thing. I actually like the idea of a pseudo-page controller where I "pretend" to haver pages (using either stub files or URL rewriting) and drop into a front controller from there and you could argue whether it is a page controller with a really large helper file or a front controller with a page style interface - the difference is pretty minimal.

Of course, the other thing to bear in mind is that with the right architecture it is even possible to mix and match page and front controllers in the same application.

Can't say any of this really make me want to run out and build a site with a page controller, but it is interesting nevertheless!
# Posted By Peter Bell | 11/28/06 7:40 AM
I don't think the Front Controller applies very well to web development projects. I understand it's place in "traditional" apps, where everything is run from a single executable. In that, it made a lot of sense.

I also understand why (and how) CF MVC frameworks use them. In that case I don't have a better solution.

But in terms of web development, I think it's better to approach every single page template as a different program. The web server treats it that way and so should we. We use 'workarounds' to maintain state, true, but a Front Controller doesn't help circumvent those workarounds. Using a Front Controller just adds more pages in your app and more processing. Before you can run your page (program) you have to figure out which "section of code" you need to run. It's extra complexity and extra processing.

I understand that this approach helps people organize their code, but I think there are other ways to organize your code without the need for a front controller that can offer the same organizational benefits.

I bet there could be a huge benefit to having a Front Controller in a Flex-based app, where everything does go down to one file. Does Cairngorm use one? I'll have to look at it.

I look forward to reading the rest of your posts in this. :-)
# Posted By Jeffry Houser | 11/28/06 8:06 AM
Jeff,

Just a quick response... while the front controller does create more processing before your page can run, and while it does create more physical pages on the server, I would argue that over time, there is probably less total code. Let's say that you have a section of your site that has ten pages. You might have to set some variable in each of those pages that denotes the section (for rendering purposes). If you had some parent page that then included those pages, this 'sectional' variable could be set once in the parent page and not duplicated in each child page.

I know this is a simple example, but I think it's the beauty of the front controller. It allows you to move duplicate code UP the action-chain to reduce the overall amount of code that is written (while the number of physical pages might be a bit higher).
# Posted By Ben Nadel | 11/28/06 8:12 AM
Of course, you COULD also solve this using inheritance if you put all of your page controller logic in cfc's. Not recommending it, but that is another approach.
# Posted By Peter Bell | 11/28/06 8:22 AM
Jeff,

I'm with Ben that the main benefit of a front controller isn't organization of code (although that is nice). It is code reuse. You can reuse controller code without having to go to the appropriate physical page file. As applications become more complex, that becomes more important.

Obviously if you delegate enough to a helper file this becomes less relevant as that can be shared between pages. I think it is pretty easy to come up with situations where it is almost a philosophical question as to whether you're using a page or front controller - they can come so close to each other.
# Posted By Peter Bell | 11/28/06 8:25 AM
Jeff, Cairngorm does indeed have a front controller (look here for a really nice diagram of how Cairngorm is structured - http://www.cairngormdocs.org/tools/CairngormDiagra...).
# Posted By Brian Rinaldi | 11/28/06 8:42 AM
Ben,

I'm not sure if i fully understand your example.

It seems to me that whether you use a front controller (or not) you'll still have to say "If Section is "this" render this else render default"

Peter,

Code Reuse is not an inherent benefit of a Front Controller. Yes, you can achieve it if you encapsulate the 'model' and 'view' away from the Front Controller. Use of encapsulation does not equate to use of Front Controller. I've seen plenty of apps that include code in the Front Controller without any thought to encapsulation.

I can achieve the same sort of reuse benefit without the use of a Front Controller. You might say that my approach is to have a lot of Front Controllers with only one execution option in each one.
# Posted By Jeffry Houser | 11/28/06 9:02 AM
Jeff,

True, the rendering logic still needs to take place. I am talking about the setting of the variables, not the checking of them.
# Posted By Ben Nadel | 11/28/06 9:20 AM
I'm going to make a few assumptions about your example. I'm sure you'll correct me if I'm wrong.

Say, we are rendering a site navigation, with Home, Contact, and About Us." If the person is in the About Us section, we want to display

Home_Inactive.gif, Contact_Inactive.gif, AboutUs_Active.gif.

If the user is in the Home Page, we want to display

Home_Active.gif, Contact_Inactive.gf, AboutUs_Inactive.gif

Is this is a good interpretation of your example?

If you create the navigation as an include, you would use something like what I stated before inside the include:

If section = Home then render Home_Active else render Home_Inactive

But, you're talking about the page that calls the include.

In a Front Controller, you just say:

Section = url.MySection

Whereas without a front controller, you'd have that line of code on every page:

Section = "Home"

on the home page, and

Section = "About"

on the about us page, and so on.

Is that the gist of your argument? I have the same line in the App 3 times (Once for home, once for About, and once for Contact) instead of just one time (in the Front Controller).

Am I right so far?

If so, I don't have a specific counter to your argument.

Assuming a controller is implemented using switch statements (ala early Fusebox stuff) it seems to me that you must have code in the controller file, but not inside an actual case. Is that the case? You are also writing code inside the controller, as opposed to encapsulating it. Is that the case?

Or do you have the same line in each case? If so, then you don't achieve any less code than my approach, because you have three lines in one file, instead of three lines three files.

You might say, it's just one line of code, and I'm okay with keeping that one line out of the switch / case.

I'd love to see a more in depth example where my 3 lines (vs your 1 line) becomes a problem that the Front Controller helps to solve.
# Posted By Jeffry Houser | 11/28/06 9:55 AM
Jeff,

That is exactly what I am talking about. But now, take it to the next level. You could have bread crumbing (that builds as you include modules), error handling, record checking (each page under a category MUST have a category record) and all that good stuff.

Truthfully, for the lower level stuff, I have found that the page vs. front controller makes littler difference. I have used the page controller for years and have recently started using the front controller (but not on all new stuff). I find it really only makes the difference for more complex actions that may or may not even need to be dealt with.
# Posted By Ben Nadel | 11/28/06 10:02 AM
Hi Jeff,

I wasn't talking about reuse of models and views but specifically about reuse of controller code. Firstly there is stuff like checking to see whether the page needs authentication and putting form and URL variables into some kind of accessible scope, but you can implement that using a page controller with a helper file.

Where the front controller becomes more relevant is when you have chunks of controller logic that could be used in multiple pages. With a front controller you can dynamically include those chnks of code based on programmatic rules rather than being limited to having to go to a specific URL to access that code.
# Posted By Peter Bell | 11/28/06 10:13 AM
Ben,

I can think of a lot of ways to build bread crumbing. I don't see how use of a Front Controller makes it easier (or harder). Ditto for error handling. Your description of "record checking" sounds like another form of error handling.

Peter,

Shouldn't "chunks of code" whether controller logic or not be encapsulated out, thus making it easy to call regardless of using a Front Controller (or not)?

As an aside, why aren't Form and URL accessible scopes? Why do I need to copy them to something else? ( Do you have an answer other than Framework purposes? )
# Posted By Jeffry Houser | 11/28/06 10:32 AM
@Jeff,

I agree that there are many ways to do all of the things that I have described. All I am saying is that when I started to move away from Page to Front controller, it's not that these things finally became "possible"... it's that they just became easier to do.

But, I have not moved onto any higher framework yet (MG, Mii)... i am still learning stuff.
# Posted By Ben Nadel | 11/28/06 10:36 AM
Hi Jeff,

Chunks of code should indeed be encapsulated out. I've just found the front controller approach to me a little more sympathetic to doing that.

There is a real debate on form and URL accessible scopes. I have always merged them and now wrap them. If you ask Michael Dinowitz (and plenty of others) they'd say that you lose information by doing that (which is true). But I find the simplification in my code worthwhile.

For example, I come to a page and I want to know a given property. Usually that property is stored in URL scope, but sometimes it is in form scope if I'm returning from a form submission, and some times (maybe first time I come to the page) it doesn't exist at all. With independent form and URL scopes I have to do something like:

cfparam URL.Myvar = default
If IsDefined("form.MyVar")
URL.MyVar = form.MyVar


Do that for 20 different variables and it gets real old, real fast.

Now lets imagine it is an ID field (say category ID for a product catalog)
You also need to run a:
URL.MyVar = ReReplace(URL.MyVar,"[^0-9]","","all")
and then:
If Len(URL.MyVar) LT 1
URL.MyVar = DefaultMyVar

I load both form and URL scopes into a business object and define the data types of the parameters that the application will require (which makes for great documentation) and it automatically checks form and URL scopes, allows for setting default values AND regex filters all values to make sure they fit their data types. I've found this kicks ass!
# Posted By Peter Bell | 11/28/06 10:44 AM
Ben,

I'd love to see a more in depth example of how something is easier w/ Front Controller.

Peter,

I don't have much else to add, except that I do expect to be at CFObjective and hope we can get together for a meal or drink or [whatever].
# Posted By Jeffry Houser | 11/28/06 2:45 PM
Jeff,

That is a tall order. The issue is that for small examples, one DOESN'T really make anything easier than the other. It's only for larger, more complex things that the difference would become apparent. I am working on a small demo project called Skin Spider (Peter, sorry to bring this up on your site). It is currently in iteration 2. I2 uses the page-controller style. All the code is posted live. During iteration 3, (which should start fairly soon), I will be converting to a home-grown front-controller methodology that I call DAX. Now, this project is very small (maybe 15 pages or something), so I don't know if there will be any noticable improvement with the use of the Front controller, but if there is, this will be a good example.
# Posted By Ben Nadel | 11/28/06 2:58 PM
Hi Jeff,

Yep. We should definitely meet up at CF Objective and grab a meal/drink. I'm really looking forwards to meeting up!
# Posted By Peter Bell | 11/28/06 3:08 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.005.