April 27, 2011, 7:51 a.m.
posted by franni
Where Do Controllers Come From?
Possibly the biggest single hurdle for many developers new to Web-based J2EE technologies is understanding how to divide the behavior of their application among classes. While the basic principles of layering and the MVC pattern may seem obvious to some, they are certainly not readily apparent to many new Web programmers, especially those who come from traditional graphical user interface backgrounds. To begin, we will review the role of the controller within a layered architecture.
Recall from the discussions of five-layer architecture in Chapter 1 and 5 that the controller/mediator layer separates the presentation of information from the domain model that holds the information. The motivation behind this separation is generally to allow more flexibility and reuse when creating or changing the views or presentation, or when making changes to the domain layer of the application.
Applying a layered architecture in this fashion allows for domain classes to be used more flexibly across multiple applications. With this in mind, you can see that the servlets and other associated classes that we write in a Web-based application fall into the controller layer of the architecture.
Controllers are responsible for taking parameters passed from the presentation layer, contacting the appropriate business logic classes, and passing the processing on to them, then taking the results and routing the user to the next appropriate screen. Servlets will perform either part or all of this function.
We haven't described how this is done, and how you discover which controllers and views are necessary for a particular application. To teach this process, we will start by examining an example application to see how you can factor it into model, view, and controller aspects.
Let's consider a simple application for managing employees taken from our case study. Our case study is comprised of several use cases for managing and tracking employee time sheets, and reporting on the time sheets submitted. Obviously, you must first have employees in the system to be able to submit a time sheet.
As with any MVC application, the first step in writing our application is to determine the model classes. In this case, this is pretty simple; we only have a single model class, Employee. We'll examine the implementation of this class in later chapters, but as you can guess, it's pretty straightforward. There are attributes for the Employee's name, ID number, age, and address.
Imagine that our users have sketched the partial design for the application shown in Figure.
In building this kind of Web-based application, users will often start with a set of page designs that have been mocked-up as static HTML. Let's assume that is the case in our application—we will show how to transform a set of Web pages into an MVC application.
How do we proceed from this mock-up showing only the screens to building an application? A simple procedure can help identify the remaining parts of the application.
First, let's identify the views in our application. This is trivial given the diagram in Figure. We can first assume that we have only JSP pages in our sample application. If there is any dynamic content in a page (meaning content that changes based on the state of the application or a user action) it should be shown in a JSP page. We would find that this means we have three JSP pages in our application:
The index page has no dynamic data, and thus does not need to be a JSP page.
The next thing to look for is the transition between the pages. Transitions arise from what we call Go buttons. A Go button is either an HTML button that submits a form or performs a GET on a URL, or a link between pages. Each Go button that performs a unique function should have its own controller. If two or more buttons refer to the same function and have the same set of parameters (or one is a subset of the other) then the two buttons represent the same transition. Each Go button represents one of two things:
In the first case, you would want a unique controller to perform that function since it could not otherwise be determined what set of information the user was requesting.
In the second case, the fact that each form or set of HTTP parameters passed on a URL represents a different data stream (with a different format; e.g., set of parameters and values) would indicate that you would want a different filter for that data stream, and thus a unique controller.
If a transition is dynamic (either the data displayed on the page changes or a particular link or submit button may ultimately direct the user to more than one page) there needs to be a controller that implements the transition to the page.
In this respect, the controller is acting as a filter in a pipes and filters architecture [Buschmann]. Data come in, are processed, and go out in a different form. Think about each controller as filtering a different data stream. Just as you wouldn't attempt to use the same filter to clean the air and the oil in your car, you wouldn't want to process multiple data streams through the same filter. In this context, you can see why you would want a different controller, or filter, for each set of input data.
Here we see that not all transitions in our example meet these criteria—for example, the link from Browse Employee to New Employee does not change the way in which the New Employee page is displayed in any way. Figure summarizes results from our analysis.
What we have on either side of the table are the views of our system. What we have identified in between are the controllers of our system. There is a different controller for each unique, active transition. So, we have identified five potential controllers:
Deleting an employee involves identifying the employee to be deleted, while updating the employee involves identifying the employee and providing the updated data. In the case study chapters that follow, we'll combine these into a single controller that handles both actions, although you can see how they could have just as easily have remained separate.