Thursday, April 3, 2008

Model View Controller

Model View Controller

Model View Controller MVC is a time tested method of separating the user interface of an application from its Domain Logic.

The primary goal of MVC is to isolate UI changes and prevent them from requiring changes to the Domain Logic of the application.

The primary reason for this division is that the user interface and Domain Logic have different drivers for change and different rates of change. By making this separation, you can change the UI without touching the Domain Logic and vice versa.

MVC is sometimes confused with other patterns that have the same goal of separating user interface from Domain Logic, such as Presentation Abstraction Control.

MVC divides an application into three concerns:

  • Model - Encapsulates core application data and functionality Domain Logic.
  • View - obtains data from the model and presents it to the user.
  • Controller - receives and translates input to requests on the model or the view.


The separation into three concerns is inspired by a information processing model where the controller represents system input, the model represents processing and the view represents the output of the system.


Model

The model encapsulates the functional core of an application, its Domain Logic. The goal of MVC is to make the model independent of the view and controller which together form the user interface of the application. An object may act as the model for more than one MVC triad at a time.

Since the model must be independent, it cannot refer to either the view or controller portions of the application. The model may not hold direct instance variables that refer to the view or the controller. It passively supplies its services and data to the other layers of the application.

See Domain Model and Transaction Script to organize Domain Logic.


Passive Model

With a passive model, the objects used in the model are completely unaware of being used in the MVC triad. The controller notifies the view when it executes an operation on the model that will require the view to be updated.

The passive model is commonly used in web MVC. The strict request/response cycle of HTTP does not require the immediacy of an active model. The view is always completely re-rendered on every cycle, regardless of changes. This may be especially true in PHP where no state is retained between requests.

Active Model

In the active model, model classes define a change notification mechanism, typically using the Observer pattern. This allows unrelated view and controller components to be notified when the model has changed. Because these components register themselves with the model and the model has no knowledge of any specific view or controller, this does not break the independence of the model.

This notification mechanism is what provides the immediate updating that is the hallmark of a MVC GUI application.

Model Adapter

It is possible to use an Adapter to add change propagation or other active model features to passive model objects, turning a passive model into an active model.


Presentation Model

The purpose of MVC is to separate UI from domain logic. In doing so, an MVC implementation typically develops a set of reusable classes for each of the concerns in the triad. Sometimes, data or behavior that firmly belongs on the user interface side of the division can conveniently be represented using the infrastructure of the model side of the division. Thus objects that would appear at first glance to be in the model are really part of the interface concern, that is the view and controller.

Some examples include scrollbar positions and column sorting.

This is sometimes called an Application Model and the pattern known as MMVC after the idea that there are two separate models.


View

The view obtains data from the model and presents it to the user. The view represents the output of the application.

The view generally have free access to the model, but should not change the state of the model. Views are read only representations of the state of the model. The view reads data from the model using query methods provided by the model.

With an Active model, the view can register itself to receive notifications when the model changes, and the view can then present a more up to date version of the model.

Sometimes generic reusable view components can be arbitrarily connected to the model in a process known as binding.

See Template View and Transform View for strategies of implementing views.


Controller

The controller receives and translates input to requests on the model or view.

The controllers are typically responsible for calling methods on the model that change the state of the model. In an active model, this state change is then reflected in the view via the change propagation mechanism. In the passive model, the controller is responsible for telling the view when to update.

In MVC, The controller is NOT a Mediator between the view and the model. The controller does not sit in between the model and the view. Both the controller and the view have equal opportunity to access the model. The controller does not copy data values from the model to the view, although it may place values in the model and tell the view that the model has changed. see Presentation Abstraction Control where the control layer acts as a mediator between Presentation and Abstraction.

The word controller is overloaded with different meanings in various patterns. see what is a Controller Anyway There are several of these controller patterns: Front Controller A single point of dispatch for incoming http requests. Page Controller Controls the flow of logic of a single web page. Application Controller Controls the flow of logic of a single application.

Because the popular MVC framework Java Struts from a PHP Perspective implements a combined Front Controller and Application Controller, some people assume that this is what is meant by the MVC pattern in the context of a web application. For the same reason, many descriptions of the Front Controller pattern on the web do not draw the distinction between a Front Controller and a Application Controller.


Relationships between components


View Controller Relationship

In traditional smalltalk MVC, views and controllers are tightly coupled. Each view instance is associated with a single unique controller instance and vise versa. The controller is considered a Strategy that the view uses for input. The view is also responsible for creating new views and controllers.

It is logical that views and controllers are strongly related, the input and output of an application is strongly related. In most GUI MVC frameworks, the view and controller are simply merged into one object. This is called Document View. The view and controller are combined as the view. The model becomes known as a document.

A passive model shifts more responsibility into the controller, as it must notify the views when they should update.

The modern web usage of MVC shifts even more of the traditional responsibilities of the view to the controller. The controller becomes responsible for creating and selecting views and the view tends to lose responsibility for its controller.

Sometimes responsibility for creating and selecting views is delegated to a specific object, this is known as the Application Controller pattern for web MVC and View Handler for GUI MVC.

The rigid request/response cycle of HTTP may make the Document View variant less popular in web applications than in GUI applications although the controller is still strongly related to the view. The HTTP request is handled by the controller, the processing to the model, and the response is handled by the view.


Model View Relationship

The view depends on the model. Changes to the model interface require parallel changes in the view.

It is very difficult to achieve a strict separation between the model and view. For example, consider the requirement “Show negative balances in red.” At first glance, this appears to be strictly an output requirement and a test might be placed into the view in roughly this form:

if balance <>

This would violate the separation of concerns in MVC. Upon further analysis it turns out that the real requirement is “show overdrawn balances in red” and the definition of overdrawn =balance < 0= should be placed in the model as that is domain specific. It is very easy for domain logic to migrate out of the model and into the view. Template View contains further discussion of this issue.


Model Controller Relationship

The Controller depends on the model. Changes to the model interface may require parallel changes to the controller.


Scale and Granularity

The MVC pattern is applicable at many different scales in an application. At the lowest level, an object oriented implementation involves three objects two with Document View. Although three objects are involved, only a portion of each object may be involved in any given MVC triad at the smallest scale. For example, a checkbox view/controller component operates on a data value from a model object. MVC is the easiest to understand and implement at the lowest level of granularity.

These small triads can be combined and composed into larger and larger triads. checkboxes and text fields into panels, panels into windows, windows into applications, etc. At each level, the separations mandated by MVC are maintained. At the higher levels, each concern might be considered a layer or package containing specific classes.

If the MVC separations are maintained at the lowest scale, it should follow that they are maintained on every higher scale.

If the three MVC concerns were simply separated into three classes for a non-trivial example, each of those classes would end up as a Big Ball Of Mud and would hardly be re-usable. Others patterns should be applied to structure the individual concerns of MVC.


Structuring views

Composite View.

The Composite pattern can be applied to the view giving it a hierarchical structure. This pattern is known as Composite View. Views are easy to decompose by partitioning the visual output of the application into nested rectangles that form the composite hierarchy.

This partitioning of the view layer creates smaller more focused view components which have more opportunity for re-use.


Structuring controllers

Because the controllers are so closely related to the view, they can also be partitioned with a parallel hierarchy to the Composite View. This is common with GUI MVC. One advantage of the Document View variant is that it is unnecessary to maintain two parallel hierarchies in this case.

The Command Pattern pattern is often used to structure the controller concern of the MVC triad. A specific set of model/view interactions is encapsulated into a command object, often called an action in the web MVC. This is commonly used in GUI MVC as well as Web MVC.

An action should not be confused with a Transaction Script. Just as it is easy for Domain Logic to bleed into the view, it is also easy for Domain Logic to bleed into the actions of the controller layer. Actions should translate input into requests on the model, create or select views, and generally provide user interface oriented services.

Actions promote reuse. They can be parameterized.

In any structuring of the controller concern, Input must be distributed to the correct controller sub components. In a GUI application, the Chain of Responsibility pattern is used along with the visual hierarchy defined by the Composite View to route input to the correct controller. _how to route input in web MVC?


Structuring models

The Domain Model and Transaction Script patterns are used to organize Domain Logic.

The Command Pattern pattern can be used in organizing Domain Logic, often as a way of implementing a Transaction Script. Using the Command pattern can promote re-use of domain logic, especially when parameterized.


Platform Independence

Typically each concern of the MVC triad has ties to a specific platform. It is possible to isolate these platform dependencies from the platform independent portions of the application by splitting each concern using the Bridge pattern.

The Context Object Pattern provides platform independence from the web server for the user interface view and controller of a web application.

The Data Access Object provides platform independence from the database server for the model of an application.


Benefits of MVC


Substitutable user interface

Different views and controllers can be substituted to provide alternate user interfaces for the same model. For example, the same model data can be displayed as a bar graph, or a pie chart, or a spreadsheet.

Some examples: Read only UI Expert and novice specific UI Different human languages Alternate input mechanisms User specific themes Alternate output formats XML, HTML, etc Alternate form mechanisms HTML forms, XForms, PDF forms


User interface components

Because MVC demands that the user interface of an application be structured into a hierarchy of objects and defines a standard relationship between these objects, generic versions of these objects are possible. They are usually called user interface components and no modern GUI environment is without a full complement of them usually combining view and controller into a single object. WACT is an attempt to provide a similarly rich set of components for web development that maintain the separation between view and controller. components promote reuse and reduce the need for special subclasses. These are known as “pluggable views” in the smalltalk MVC literature.


Multiple simultaneous views of the same model

Multiple different views can be active at the same time. Each view simultaneously and independently presents the same information from the model. This applies more to GUI MVC than web MVC.


Syncronized views

The change propagation mechanism insures that all views simultaneously reflect the current state of the model.


Easier user interface changes

Changes affecting just the user interface of the application logic become easier to make.


Easier testing

With MVC it can be easier to test the core of the application, as encapsulated by the model.


Drawbacks of MVC


Increased complexity

If reading this page doesn’t convince of you the complexity of this pattern, consider all of the auxiliary patterns that co-occur with MVC.


Close coupling of views and controllers to model

Changes to the model interface require parallel changes in the view and may require additional changes to the controller. certain code changes become more difficult.


Potential for excessive updates

The change propagation mechanism can be inefficient when frequent model changes require many change notifications. This is generally not as much of a problem if a passive model is used.


Close coupling between view and controller

strict separation is difficult if not impossible.


What goes where?

A common question about web MVC is “where does this go?” This question arises from the desire to concretely divide every portion of an application into one portion of the triad. In practice, however, a strict separation of concerns into three parts is difficult to achieve, perhaps impossible. The difficulty of separating view and controller is discussed in the Document View variant. Perhaps the effort to achieve strict separation exhibits diminishing returns and is simply not worth pursuing to the fullest extent.

_talk about how user interface models and domain logic bleed into the view and controller add to the confusion._

_Mediator based definitions of MVC also add to the confusion._

That said, the best guide to partitioning the application is to follow the input, processing, output form of the pattern.


When NOT to use MVC

The need to separate domain logic from presentation is almost an unquestioned axiom of object oriented design. Yet, many successful projects have not done this at all. Standard usage of PHP freely mixed UI and domain logic. Microsoft’s .NET architecture encourages domain logic to be mixed with user interface. Many successful software packages have been written without using the MVC pattern. see Separate Domain From Presentation for an alternate viewpoint.

Implementing MVC is complex and difficult. Following the You Aren't Going to Need It principle, one might hold off implementing MVC in an application until a need for one or more of the benefits of MVC manifests itself. Carefully weigh the benefits and drawbacks of using MVC before implementing this pattern in your application.

No comments: