Tuesday, December 21, 2010

Model-View-Controller Design Pattern

Summary: The MVC design pattern enables one to cleanly decouple the model from the view in large systems.

Content actionsA program can often be divided into two parts:

  • The "Model" : the internal working "guts" of the program where the processing actually takes place.
  • The "View": the input and output of the program which interacts with the user.
The view takes the user input and passes the information onto the model. The model outputs information to the view, which then presents it to the user. In the spirit of loose coupling the following ideals should be enforced:
  • The model should operate independently from the manner in which the view interacts with the user.
  • The view should be tailored to meet the interaction needs of the user, independent of the model below it.
This has the following implications:
  • The input/output interface of the model will not necessarily match as the corresponding input/output interface (the model side, not the user side) of the view.
  • A model should work with a number of different views.
  • A view should work with a number of different models.
  • In general, in order for a model and view to communicate, an "adapter" object is needed to translate the output of one into the input of the other.
  • Neither the model nor the view is capable of creating the adapter that connects them because each is unaware of the other.
Therefore, what we need is one more component, the "Controller". The controller "knows" about both the specific model and specific view being used. The controller's job is:
  • To instantiate both the model and the view.
  • To instantiate the adapter(s) used to communicate between the model and view.
  • To establish the connections between the adapter and the view and between the adapter and the model.
The Model-View-Controller ("MVC") design pattern decouples the model from its view, enabling loose coupling and the ability to change one without affecting the other.
Figure 1: MVC pattern showing how the view and model are decoupled.
Block diagram of the MVC pattern
Block diagram of the MVC pattern
To communicate from the model to the view and vice versa, the Command Design Pattern is used. In short, a command is encapsulated as an object, very similarly to a strategy. To invoke the command, the comand issuer executes a specificly designated method of the command object. The issuer is unaware of and thus decoupled from the recipient of that command. The model-view-controller pattern, the model and view issue commands to each other. Since the model and view are unaware of each other's interfaces, those commands are also interface adapters.
The command adapters used between the model and the view come in several flavors:
  • The "null" adapter: This is a direct connection between the model and view. One should consider this a lucky coincidence and the design of neither the view nor the model should be driven by attempts to create null adapters.
  • The object adapter: This type of adapter pattern uses composition to achieve its purpose. the adapter is a subclass of the class that one side wants to communicate with. It holds an instance of the class the other side wants.
  • The class adapter: This type of adapter uses multiple inheritance. It inherits from the class for one side or implements its desired interface. It also implements the interface for the other side. This type of adapter does not promote total decoupling of the view from the model however, so it is not recommended for those sorts of situations.
  • The "dispatching" adapter: This type of adapter is used in situations where an observer-observable pattern is desired but the command issuer does not support it. The adapter receives a single command but then relays that command to a number of different receievers.
For a more detailed discussion on how adapters work, see the module on the Adapter Design Pattern.

Multi-piece Models and Views

Often the model is not a single monolithic piece, but rather a collection of loosely coupled sub-models. One can still use a MVC pattern without resorting to encapsulating the submodels into a single model object by considering this:
To any given sub-model, the rest of the sub-model pieces are simply part of its view.
Likewise, the same ideas apply if the view is broken into sub-views.
Thus, the controller can treat the sub-model pieces and the sub-views equivalently. The controller simply is tasked to hook all the pieces together to form a cohesive total program.

GIVE FEEDBACK:

No comments:

Post a Comment