MVC and Event-Driven Programming
Posted by David Chandler on September 10, 2005
A dynamic Web application has more in common with a traditional Windows GUI application than with a static Web site. A Web application, similar to any GUI application, typically consists of forms populated with database data. As with any Windows application, forms have action buttons and familiar controls such as check boxes and text input fields. Fifteen years ago, Microsoft revolutionized GUI programming with the introduction of Visual Basic and the event-driven paradigm. Arguably, the industry transition from procedural to event-driven code has been every bit as significant as the transition to object-oriented programming.
Until recently, however, the shift to event-driven programming was completely missed by Web application developers. Most likely, this is because early on, the Web was mostly about sites, not applications. HTTP and HTML are page-oriented, and scripting languages like ColdFusion, ASP, and JSP made it easy to develop dynamic “pages.”
The page-oriented paradigm works fine for small applications with uncomplicated navigation, but it quickly breaks down for large applications with a lot of user input. The root of the problem is one of encapsulation. A typical script “page” contains at least two different kinds of code:
- Action code that processes input from the submitted form
- Presentation code that displays the result page
These two things do not belong together in the same unit of code. For example, suppose a form has two buttons, one which goes to another form to do some kind of lookup, and one to process the completed form. Regardless of which button is pressed, you want to save the data from the initial form so you can use it later. Typically, the “page” referenced in the form action attribute would save the form data regardless of which button was clicked, then include or forward to a new “page” based on a form variable like a named submit button.
From an encapsulation point of view, there is no reason that the unit of code that saves the form data should have to know about the navigation changes associated with the different buttons on the form. The more complex your navigation, the more apparent this becomes. In one application I worked on, there were hidden variables named “what” (no kidding) and “origWhat” that got copied from page to page to keep track of the user’s page flow. Many pages had code blocks like
if (origWhat = “page x”)
// Came from page A
do one thing
do something else
In essence, this and the previous example are a kind of event-driven programming where each button represents an event, but the navigation rules and processing code are all jumbled up together. Code like the block above is dependent on the preceding page flow, yet the exact nature of the dependency is not clearly visible in the code. Hidden dependencies make code brittle.
Event-Driven Web Frameworks
Enter event-driven Web frameworks like Fusebox, Struts, and JavaServer Faces (JSF). These frameworks decouple event handlers (action processing) from view selection (navigation). This is commonly done by using a navigation rules file that specifies all the page transitions independently of any code that handles events. This is perfectly in keeping with Chandler’s Law of Coupling:
Where dependencies exist, represent them explicitly in one place instead of hiding them in many places.
Of the frameworks mentioned, the JSF navigation controller is the most flexible, allowing you to specify the next view based on the previous view, the event that fired (which button was pressed), the outcome of that event (success, failure, etc.), or any combination of these. In addition, JSF devotes an entire step in the request lifecycle to automatically saving the data from the previous form, so you don’t have to worry about that any longer. More on that in a coming article.
In a nutshell, the event-driven paradigm for dynamic Web applications fulfills Chandler’s First Law of Application Design:
Choose a design paradigm that most closely fits the system you’re trying to model.
Event-driven Web frameworks let you code a Web application more like the GUI application that it really is. If you want robust, maintainable code, you need the right tool for the job.