Recently I asked a group of developers to review how they build Web applications. With over 100 ColdFusion applications/sites in place, I wanted to see what we could do to reduce the cost of adding new applications and new features while containing our maintenance costs. Mostly I wanted to look at building and exploiting common services rather than writing and maintaining numerous standalone applications that implement similar features. For example we have several applications that allow people to book appointments and schedule meetings. Each of these applications implements some amount of scheduling and calendaring within its own database. A robust scheduling engine should let us retire a lot of our code while building more capable applications.
Part of the group's response was to review ColdFusion frameworks like FuseBox, ColdSpring, Model-Glue, and ColdBox. They wanted to see if adopting one framework would provide benefits like easier maintenance. If every application were written using the same framework it should be easier to support all of them.
With the exception of ColdSpring, which is primarily a dependency injection/inversion of control framework, the frameworks all support the Model-View-Controller (MVC) pattern. Controllers have a very important place in these frameworks. In simple terms they handle Get and Post requests which are mostly form submissions. For example a front controller can handle form submissions from multiple pages and dispatch appropriate commands so that the right models are updated and the appropriate views are returned to the user. Front controllers are an important way to bring order to what otherwise might look like a mess of unrelated web pages and business objects.
But what if you are building a web application with a rich client? For example, if you are using Flex or AJAX and don't need to submit any forms? Do you still need an MVC framework?
I think the answer is most likely no. I don't think you have to have controllers on the client or on the server.
MVC was developed in the late 1970s and was used in Smalltalk 80. It's been a long time since I saw Smalltalk 80 at Xerox and I don't remember MVC from back then. But, from what I've read since, for every model/view of data that could be manipulated by the user, a controller was required. The controller handled mouse and keyboard events and could pass messages on to other controllers if necessary. As GUI/application frameworks evolved, including later versions of Smalltalk, developers were not required to instantiate controllers to handle user events. Adobe's Flex framework has no controllers in the Smalltalk 80 sense. You don't have to do the extra work of instantiating a controller to find out when a menu item is selected, a list is scrolled, or a button has been pressed. You just ask those components to tell you when an event occurs via their addEventListener method. If you use data binding you often don't even need to use addEventListener or write code to handle events and then update controls. The Flex framework can often just take care of simple updates for you.
I think it may be helpful to make a distinction here between how post Smalltalk 80 application frameworks work internally and how developers can cost effectively use things like the Flex framework to build applications. Developers who use modern rich-client frameworks do not have to create controllers to manage events. What a runtime and its frameworks do internally is a different story. In the case of the Flash/Flex event system and Flex data binding, they are designed to make adding controllers unnecessary. So much so, that Flex add-on frameworks structured around controllers look like anti-pattern bolt ons to me. The component hierarchy in Flex provides an easy way to implement some facets of hierarchical state management. Events that can't be handled within a container can bubble up to a container that can handle them. Front controllers break down the modularity of applications by forcing you to wire up events at a global level and make hierarchical state management less practical.
Rich Client Web Application Layers
Earlier I mentioned that I wanted to look at building and exploiting common services rather than implementing similar features in each application. Simple standalone Web applications only need three layers: presentation, domain, and data source. The presentation layer is responsible for displaying information and responding to user requests. The domain layer is where all the "business logic" and domain model reside. It is the heart of the application. The data source is most often a relational database. Of course the boundaries between these three layers are somewhat porous. Stored procedures contain business logic. Client-side validation code enforces simple business rules and may implement simple workflows. But, in general, it is not too difficult to divide traditional thin-client Web applications into presentation, domain, and data source layers - even if those layers are distributed across different physical tiers.
Now, let's consider what happens to application layers when we start building applications based on services like a scheduling engine or content management system. A well-known approach to this problem is to split the domain layer into two parts often called the application and domain layers. The result is four layers:
Presentation - display information including application state and handle user input.
Application - implement workflow and transient application state.
Domain - this is the domain model that represents entities in the business model and implements business rules.
Data Source - database or other infrastructure.
Splitting application state and workflow off from the domain model makes it easier to build applications on top of services. There is no need to have a 1:1 mapping of one application to one domain model. For example, applications may make use of a scheduling service, course management system, user management service, and a CMS. Others may only use the scheduling and user management services.
Returning to rich-client applications and the physical boundary between client and server what does this mean? I think it means that an application's server-side business logic will be mostly transactional and that most everything else, including a lot more business logic, will happen on the client.
If the role of application servers is reduced to transactional business logic there is little need for handling user actions on the server like form submissions and the idea of implementing front controllers as a matter of course for every application or service starts to look - at least to me - like an anti-pattern.
Of course not every application is a rich-client application. Some applications need to present a forms-based Web front end for one class of users and provide a rich client application for others. Something like a front controller probably makes sense for the forms-based part of the application. But, I think it needs to be isolated for just that purpose, and that it's time to expunge the idea that controllers are always essential to handle user actions. I think it's time that Web application frameworks start to catch up to where desktop applications frameworks have been for a long time. If the strategy pattern is needed it can be used. That doesn't mean we always need controllers.
There is a section in the first chapter of the book titled Design Patterns in Smalltalk MVC, where the initial Smalltalk MVC pattern is related to the patterns the authors chose to describe later in their book. For example the Model-View in MVC is similar to the Observer pattern, the Smalltalk CompositeView class supports composite views which are similar to the more general Composite pattern, and selecting a Controller subclass to implement a response to a user action is similar to the book's description of the Strategy pattern. Of course those are only three of the book's 23 patterns.
Here are two papers on Smalltalk MVC that provide some idea of what Smalltalk MVC was about from a developer's perspective:
I highly recommend this article from Martin Fowler for a thoughtful and historical perspective on the evolution of rich client systems:
Paul Williams, with Adobe consulting, takes a closer look at Martin Fowler's presentation patterns by implementing them in Flex.
A short blog post from Sho Kuwamoto created an interesting discussion on Flex and MVC:
And, James Ward posted a Flex Best Practices video here with some interesting comments on MVC frameworks and related things.
Much of what I've written here on application layers is a pale reflection of what you can find in these two books:
Fowler's first chapter describes layers in Web applications, in particular the "Three Principle Layers" while the second chapter introduces service layers and organizing domain logic.
Evan's fourth chapter has a nice discussion of layered architectures including the User Interface, Application, Domain, and Infrastructure layers. His focus on isolating the model in the domain layer and description of the "Smart UI" anti-pattern are worth careful reading in light of how easy it is to build rich-clients using frameworks like Flex.