Monday, October 19, 2009

The MVP pattern

The MVP stands for Model-View-Presenter and it is a user interface (UI) design pattern engineered to facilitate automated unit testing and improve the separation between the UI (rendering stuff) and the business logic.
  • The Model defines the data to be displayed in the user interface (UI)
  • The View is an interface that displays data (the model) and routes user commands to the presenter to act upon that data
  • The Presenter handles both the model and the view. It retrieves data from repositories, persists it, manipulates it, and determines how it will be displayed in the view. The Presenter provides all the UI logic
The MVP pattern is implemented using different MVP flavors, each of them having the pros and the cons.

MVP - Passive View Pattern

  • The View is as dumb as possible and contains almost zero logic.
  • The View and Model are completely separated from one another.
  • The Presenter is a middle man that talks to the View and the Model.
  • The Model may raise events, but the Presenter subscribes to them for updating the View.
  • There is no direct data binding. The View exposes setter properties which the Presenter uses to set the data.
  • All state is managed in the Presenter and not the View.
+ maximum testability surface
+ clean separation of the View and Model
- more work (for example all the setter properties) as you are doing all the data binding yourself

MVP - Supervising Controller Pattern

  • The Presenter handles user gestures.
  • The View binds to the Model directly through data binding. In this case it's the Presenter's job to pass off the Model to the View so that it can bind to it.
  • The Presenter will also contain logic for gestures like pressing a button, navigation, etc.
+ the amount of code is reduced because of the data binding
- less testability (because of data binding)
- less encapsulation since the View talks directly to the Model

3 comments:

suman said...

In the passive view , the presenter still calls on the setter of the view hence presenter is tightly coupled with the view what if , the presenter could hand over a standard model object to view and view would know how to update itself, what do you think will it be a good idea ??

Admin said...

The View is an interface so the Presenter knows nothing about the View's implementation. There is no tightly coupling here.

The View uses primitive data types only (string, bool, int, object). So let's say we have a UI and we want to display a title. Here is the View setter:

interface IView
{
string Title {set;}
}

Now let's say we want to implement this view using a TextBox for displaying the title, and we also want a second implementation that uses a Label for the same job.

class frmTextBox : Form, IView
{
...
public string Title
{
set { this.txtTitle.Text = value; }
}
...
}

and the second one...

class frmLabel : Form, IView
{
...
public string Title
{
set { this.lblTitle.Text = value; }
}
...
}

The Presenter will look like this:

class Presenter
{
private IView view;
...
public void UpdateTitle
{
this.view.Title = "A Good Title";
}
...
}

So, the Presenter knows nothing about the way the title is displayed but it is able to handle both implementations with no code updates.

Using a dummy Model to be handled by the View is not a good idea because you have to provide some logic in the View. If you want to change the View from WinForms to Infragistics/Telerik controls you have to re-implement this logic. And of course, you loose testability.

This is way you have to provide only primitive data type to the View.

Brian Wilkins said...

How would you transfer a large IList, for instance, from a Model to the Presenter if the IView only deals in primitive types?