03/09/2011

Page Controller Vs Front Controller Pattern

How do you best structure the controller for moderate / complex Web applications so that you can achieve reuse and flexibility while avoiding code duplication?

MVC has been a tried and tested method of structuring your applications for a long time. Generally MVC mainly focuses on separating model and view and less attention on the controller. Specially in rich client applications the view and the controller tends to lie close together. But in web applications this separation is more critical since the view is essentially happening at client side (browser) while the most of the controller sits in the server side.
There are 2 basic ways of structuring the 'C' of the MVC, i.e Controller. The 2 basic methods are the Page Controller method and the Front Controller method.

The Page Controller solution describes a single object per logical page. This solution breaks down when you need to control or coordinate processing across multiple pages.
For example, suppose that you have complex configurable navigation, which is stored in XML, in your Web application. When a request comes in, the application must look up where to go next, based on its current state.
As Page Controller is implemented with a single object per logical page, it is difficult to consistently apply a particular action across all the pages in a Web application.
Now in order to reduce the overhead of repetitive code, and to provide consistency in features provided on all pages, we should move to Front Page Controller pattern.

Page Controller: The Page Controller is the more simple and straight forward way. Every request to the server is directed to a page (controller) of its own.

Front Controller : In Front Controller all requests will reach a single controller and it will dispatch the task to appropriate command class.

Let us analyze the 2 methods with respect to several aspects.

Criteria

Page Controller

Front Controller

Complexity / Ease of Implementation

Low complexity. Suits simpler web applications. Most of the time the commercial web application frameworks have built-in support.

Complexity is high compared to page controller. The single controller it self can be complex. However many CMS frameworks have this built in. (Eg: DNN)

Code Duplication / Code quality

Duplication can be high as the application grows. Has to implement a BaseController from which all page controllers extend.

Low code duplication. All common tasks can be put inside the front controller

Testability

Can be low. Has to go for a 2 part controller where one is HTTP dependent and the other is independant and testable.

The front controller will only handle transfer of the request to independent commands which could be testable. Has to be careful

Adaptability/Flexibility

When the pages of the web application is very different from each other, the code duplication can be higher. If you try to counter this with seperate inheritance tree, it can grow complex soon.

Since the front controller is centralized it's highly configurable. That's why many CMS frameworks use front controller to increase flexibility.

Performance

No extra bottleneck if plain page controller is used. However if a deep inheritance hierarchy is used performance can be a bit lower than normal.

The single front controller can end up being a bottleneck since it answers to all requests. Should avoid doing I/O or DB calls in the front controller as much as possible.

Thread Safety

The same page controller instance might handle (Depending on the web application framework, eg: ASP.Net) requests for the same page and thread-safety has to be considered. Use of static instances might be problematic.

Front controller can instantiate new command objects for each request and ensure thread safety at controller level. However model code still has to be thread safe.

Work distribution and responsibility

Easier to distribute the work among developers since each area of work can be done completely separately

Each developer has to have a good understanding of the Front Controller behavior as everything depends on it.