J2EE Blueprints Design Pattern
Model View Controller (MVC)

 name

Model View Controller (MVC)

 abstract

Increases reusability by partially decoupling data presentation, data representation, and application operations. Enables multiple simultaneous data views.

 intent

Facilitates maintenance, extensibility, flexibility, and encapsulation by decoupling software layers from one another.

 category

Structural Pattern

 motivation

Graphical, single-user applications are commonly organized around event-driven user interfaces. The developer draws a user interface with an interface building tool, then writes blocks of code that execute application actions in response to user input. Many interactive development environments encourage this sort of code structure, since they emphasize building the interface first and asking questions about functionality later. Some design methodologies emphasize starting with the user interface, which all too often solidifies into a final system design. The result is a program organized around user interface elements and user actions on those elements, with persistent data manipulation, application functionality, and display code completely intertwined.

Code structured in the way described above can be successful for small, single-user systems whose functionality requirements change slowly over time. But such a structure is inadequate for larger, long-term, distributed projects for several reasons:

  • More sophisticated applications often require multiple ways of viewing and manipulating the same data. The result is often similar data calculated or accessed in different ways, resulting in display value inconsistencies. Even if the displayed data are correct, any change to data display must be updated in multiple places, opening the door for software flaws.
  • Applications that require long-term maintenance need a structure that maintainers can learn and undestand. Figuring out what an application does is very difficult when data manipulation logic, formatting and display code, and user event handling are entangled.
  • New interfaces must be developed from scratch, since the application logic is buried in the code for a different interface.
  • When new functional requirements appear, it's difficult to find the code that needs to be changed or extended.
  • Porting the application can be made much more difficult. If business logic code accesses a particular vendor's product (a database, for example) from everywhere in the application, replatforming can be next to impossible.
  • Distributed systems implemented in this way often perform redundant data accesses, because user interface elements individually query for similar information. Also, maintaining consistency between multiple viewers of a shared, dynamic data store is very difficult. The solution simply doesn't scale.
  • Only a very few developers can work on the application at once, since a change to the code anywhere has side effects everywhere.
  • Unit testing is difficult because it is manual, and coverage is difficult to determine.
  • Modular application development is much more difficult, because everything depends on everything else.
  • Code is less reusable, because each component depends on many other components in order to do anything. Dependencies between components make the components less usable in other contexts.

Distributed application designs can be improved by separating the data model from the various ways the data can be accessed and manipulated. The Model-View-Controller ("MVC") design pattern separates the application data from both the ways the data can be viewed or accessed, and from the mapping between system events (including user interface events) and application behaviors.

The MVC pattern is composed of three component types. The Model component represents the application data, plus methods that operate on that data, with no user interface. The View component presents the data to the user. The Controller component translates user actions into operations on the Model. The Model, in turn, updates the View to reflect changes to data. The duties these component types perform, and the relationships between components, appear in Figure 1 below.

Figure 1. Duties and interrelationships of MVC component types

 applicability

Use Model View Controller:

  • for distributed applications
  • for larger applications
  • for applications with a long lifetime
  • to enhance interface and back-end portability
  • where identical data must be viewed and manipulated in multiple ways.
  • to improve maintainability
  • to support concurrent, modular development with many developers
  • to facilitate division of labor by skill set
  • to facilitate unit testing
  • with enterprise beans that are reusable across applications

 structure

Figure 2. MVC in the Java Pet Store

 participants

Model

  • abstracts application functionality
  • encapsulates the application state
  • provides access to application functions
  • manages persistence, when there is persistence
  • notifies interested parties when data change
View

  • abstracts data presentation
  • presents data to the user
  • maintains consistency with model data
Controller

  • abstracts user interaction/application semantic map
  • translates user inputs into application actions
  • select appropriate data displays based on user input and context

 collaborations

Model

  • notifies Views when it changes application data
  • can be queried by the View
  • provides application functionality access to the Controller
View

  • presents Model data to the user
  • updates display when informed of data changes by the Model
  • forwards user input to the Controller
Controller

  • translates user inputs into application actions on the Model
  • selects the View to present based on user input and Model action outcome(s)

 consequences

Using MVC can have the following consequences:

  • Clarifies design by separating data modeling issues from data display and user interaction.
  • Allows the same data to be viewed in multiple ways.
  • Allows the same data to be viewed by multiple users.
  • Improves extensibility by simplifying impact analysis.
  • Improves maintainability by encapsulating application functions behind well-known APIs, and decreasing code replication ("copy-paste-and-hack").
  • Enhances reusability by decoupling application functionality from presentation.
  • Makes applications easier to distribute, since MVC boundaries are natural distribution interface points.
  • Can be used to partition deployment and enable incremental updates.
  • Facilitates testability by forcing clear designation of responsibilities and functional consistency.
  • Enhances flexibility, because data model, user interaction, and data display can be made "pluggable."

 implementation-issues

MVC designs may encounter the following pitfalls:

  • Since components can't take advantage of knowledge of other components' implementation details, performance must be balanced with the other considerations above. Skillful API design can overcome this pitfall to some extent.
  • MVC may not scale well in distributed systems, if communication volume and latency issues are not carefully addressed.
  • MVC applications can be difficult to maintain if the Model's API is in flux, since the Controller is written in terms of the Model API. Implementing Controller/Model communication as a Command pattern can minimize API drift and provide a hook for Controller extensions to handle new Model functions. Alternately, in many cases it's possible to use an Adapter to provide backward API compatibility.

 sample-code

The Java Pet Store sample application design is a MVC architecture. As shown in Figure 2 above, the JPS Model is composed of enterprise beans, the Views are implemented by a combination of JSP pages (written in terms of Web Tier JavaBeans components), and Controllers are Session beans and supporting controller classes.

Java Pet Store views are implemented in an HTML browser as JSPs, based upon the master template jsp, located in the Java Pet Store distribution in at template.jsp. Other view classes in the Web Tier include:

The Controller classes in the Web Tier include:

The Model classes in the Enterprise and EIS tiers include:

  • ModelManager.java - Provides a single point of access to all Model objects. Other Model classes typically end in "Model.java" (for example, OrderModel.java, CartModel.java, etc.)