Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coldfusion, whats the advantage of front controller design over page controller?

I'm from a non-computing background and I'm struggling to getting my head around MVC design approaches and frameworks in general. I "get" code re-use, and separation of logic from display, and I "get" encapsulation and decoupling, but I don't get this.

At the moment I simply put everything in root, a separate subfolders for images, cfcs, and _includes, all database interaction via cfcs. I do all my processing at the top of the page, then a comment line then display/page layout below that.

Most of the frameworks I have looked at seem to favour a front controller, so my simplistic version of a top controller MVC design would be a subfolder for cfcs, controllers, and views and a big switch statement in index.cfm

<cfif not IsDefined("URL.event")>
    <cflocation url="index.cfm?event=home" addtoken="No">
</cfif>

<cfswitch expression="#url.event#">
    <cfcase value="home">
        <cfinclude template="controllers/home.cfm"/>
        <cfinclude template="views/home.cfm"/>
    </cfcase>
    <cfcase value="about">
        <cfinclude template="controllers/about.cfm"/>
        <cfinclude template="views/about.cfm"/>
    </cfcase>
</cfswitch>

.. but what real advantage does that give me over a page controller design? Unless it's just the kind of sites I write, I always seem to find that the controller logic is specific to a view, its not like one controller could fit several views or several controllers could output to one view, so what would be the point of separating them?

The light hasn't come on for me yet, any pointers?

like image 523
Saul Avatar asked Feb 07 '11 22:02

Saul


2 Answers

By "top" controller, I think you mean "front" controller, a single point of entry for requests into an application. As @bpanulla wrote, most ColdFusion frameworks use this design pattern. This becomes particularly interesting with URL rewriting, where it becomes easy to have search engine safe URLs by intercepting the a URL (e.g. domain.ext/i/am/friendly.ext) and routing it to some standard file such as index.cfm while making the requested URL a parameter (often as a request header). This also makes site redesigns where URLs change easier because it lends itself well to aliasing or redirects.

As far as controllers are concerned, they are usually tightly coupled to a particular URL or URL pattern. It's possible be more loosely coupled with controllers, but in practice I find that's an emergent property after multiple refactorings. What should be underlying the controller is one or more calls to a service layer that talks to the database, executes business process, creates stateful entities, etc... Then the controller receives the service layer's outputs and places them into whatever mechanism (e.g. an event object) is used to pass data to the view(s).

It's the service layer that's meant to be reusuable not the controllers. The controllers are merely an extension of whatever framework an application works within. The idea being that you should be able to switch frameworks with very little impact to the views and service layer. The piece that needs to be touched are the controllers.

So a given service object in a service layer should be able to service multiple controllers. For example, consider showing a logged in users' information as a widget on a site. There might be different pages served by different controllers, but each would call the same service object to get logged in user data that presumably might be given to the same view that renders the widget.

Update: Front Controller Advantages

  • Security: centralized authentication and authorization.
  • i18n & l10n: inject the right language pack into the request globally
  • Process Orchestration: think multi step checkout process for a shopping cart where you don't want the back and forward buttons to work - by routing everything through the front controller you're able to enforce what step (i.e. the state)
  • Logging & Tracking: easily add Google Analytics or other request tracking to a site by making the addition in just one place
  • Error Handling: centralized behavior

Now many of these items can also be done using <cferror> and Appplication.cfc, but I find it easier to have one centralized point.

Useful Links

  • http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
  • http://msdn.microsoft.com/en-us/library/ff648617.aspx
like image 78
orangepips Avatar answered Sep 21 '22 02:09

orangepips


You actually implemented the crux of Fusebox (http://www.fusebox.org/) with what you wrote. There's nothing wrong with that, and most of the ColdFusion community used something similar to that for many years - Fusebox was the most-used CF framework (in my experience) until just a few years ago when ModelGlue, Mach-II and the other second generation CF frameworks came about.

One thing I can point out is that your approach to controllers (as .cfm files) actually does not enforce encapsulation in the typical OOD fashion, with specific arguments going to an object method call. Unless you are extremely dilligent, over time your .cfm controllers may wind up accumulated a large number of undocumented parameters that alter behavior to solve one problem or another.

With the various frameworks you also get nice features like Application, Session, and Request specific code (onApplicationStart, onRequestEnd, etc). But you can always get those through a simple Application.cfc.

like image 39
bpanulla Avatar answered Sep 22 '22 02:09

bpanulla