Friday, September 11, 2009

Model View Presenter (MVP)

Introduction

In this article we will understand MVP, execute a sample project with MVP, implement the same using windows UI and then finally we will discuss about the differences between MVP and MVC.

Please feel free to download my free 500 question and answer videos which covers
Design Pattern, UML, Function Points, Enterprise ApplicationBlocks, OOP'S, SDLC,
.NET, ASP.NET, SQL Server, WCF, WPF, WWF, SharePoint, LINQ,SilverLight, .NET
Best Practices @ http://www.questpond.com/

Model View Presenter (MVP)


Pre-requisite

This article assumes that you know MVC. In case you want to refer the MVC go
to the following article "The 3 Musketeers: Model, View and Controller using
HTTPHandler – Part 1 & Part 2"

The simple stock project


The best ways to understand any architectural concept is by taking a small practical sample and then apply fundamentals on the same. So let’s first discuss a simple scenario and then let’s think how MVP fits in to the same. Below is a pictorial representation of a simple stock project. We can increase the stock value and decrease the stock value. Depending on the stock can have three status overstocked, under stocked or optimally stocked.


We have three scenarios depending on which the UI will change color.


Analyzing the project

What we will do is define the problem logic in two parts:-
• Presentation logic
• Business logic


The other responsibilities look fine let’s concentrate on the last responsibility which we have marked in red color where the UI needs to change colors depending on the stock value. This kind of logic in presentation is termed as presentation logic.

So what’s the problem?

If you look from a generic perspective the work responsibilities allocated to the business object and the user interface look fine. There is slight concern when we look at the presentation logic.

We have three big problems:-

Reuse of presentation logic
If we want to reuse the presentation logic in some other UI type like windows. I mean to say we have implemented this logic in ASP.NET web pages and we want to reuse the same in windows. As we have the presentation logic is tied up in the UI code it will be difficult to decouple the same from the UI. We also would like to use the same presentation logic with other pages of same types.

Presentation is tied up with the business object
The presentation is tied up with the business object. It’s doing lot of work checking the stock status using the business object and changing the UI colors accordingly.

UI testing
If we want to test the user interfaces it becomes difficult as the UI is highly coupled with the UI. It becomes difficult to test these parts as different pieces.

MVP (Model View Presenter) the solution

So let’s take the above three problems and see how we can solve it. MVP will help us solve the above three problems.

Problem 1:- Reuse of presentation logic
If we want to reuse the presentation logic irrespective of the UI type we need to move this logic to some separate class. MVP does the same thing. It introduces something called as the presenter in which the presentation logic is centralized.

Note: - In this scenario the presentation logic is simple. In real projects you will find the presentation logic complex and there is lot of bandwidth of reuse in other user interfaces.
Problem 2:- Presentation is tied up with the business object
To decouple the presentation from the business object we introduce an interface for every UI. The presenter always talks through the interface and the concrete UI i.e. the web page communicates also through the view interface. In this way the model is never in touch with the concrete UI i.e. the ASPX or windows interface. All user interface should implement this interface so that the presenter can communicate with the UI in a decoupled manner.

Problem 3 will get solved if we solve the first two problems.

Implementing MVP in the stock project

All events are first sent to the presenter. So all the events needs to connect to some methods on the presenter. All data needed by the UI i.e. in this instance we need the stock value and the color should be defined in the interface so that presenter can communicate using the same.

So below is the interface for the ASPX page. We need the stock value so we have defined a method called as ‘setStockValue’ and we also need the color so we have defined a method called as ‘setColor’.
public interface StockView
{
void setStockValue(int intStockValue);
void setColor(System.Drawing.Color objColor);
}


The presenter class will aggregate the view class. We have defined an ‘Add’ method which takes the view object. This view will set when the ASP.NET page starts.
public class clsPresenter
{
StockView iObjStockView;
public void add(StockView ObjStockView)
{
iObjStockView = ObjStockView;
}
.....
.....
.....
}


When the user presses the increase stock button it will call the ‘increasestock’ method of ‘clsPresenter’ and when the decrease stock button is called it will call the ‘decreasestock’ method of the ‘clsPresenter’ class. Once it increments or decrements the value it passes the value to the UI through the interface.
public void increaseStock()
{
Stock.IncrementStock();
iObjStockView.setStockValue(Stock.intStockValue);
ChangeColor();
}
public void decreaseStock()
{
Stock.DecrementStock();
iObjStockView.setStockValue(Stock.intStockValue);
ChangeColor();
}


We had also talked about moving the presentation logic in the presenter. So we have defined the ‘ChangeColor’ method which takes the status from the ‘Stock’ object and communicates through the view to the ASPX page.
public void ChangeColor()
{
if(Stock.getStatus()==-1)
{
iObjStockView.setColor(Color.Red);
}
else if (Stock.getStatus() == 1)
{
iObjStockView.setColor(Color.Blue);
}
else
{
iObjStockView.setColor(Color.Green);
}}


The View

Now let’s understand how the UI will look like. The UI either it’s an ASPX or windows should inherit from the stock view interface which we have previously explained. In the page load we have passed the reference of this page object to the presenter. This is necessary so that the presenter can call back and update data which he has received from the model.
public partial class DisplayStock : System.Web.UI.Page,StockView
{
private clsPresenter objPresenter = new clsPresenter();
protected void Page_Load(object sender, EventArgs e)
{
objPresenter.add(this);
}
…..
…..
…..
}}


As we have inherited from an interface we also need to implement the method. So we have implemented the ‘setStockValue’ and the ‘setColor’ method. Note that these methods will be called by the presenter. In both the buttons we have called the ‘increaseStock’ and ‘DecreaseStock’ method of the presenter.
public partial class DisplayStock : System.Web.UI.Page,StockView
{
private clsPresenter objPresenter = new clsPresenter();
protected void Page_Load(object sender, EventArgs e)
{
objPresenter.add(this);
}
public void setStockValue(int intStockValue)
{
txtStockValue.Text = intStockValue.ToString();
}
public void setColor(System.Drawing.Color objColor)
{
txtStockValue.BackColor = objColor;
}
protected void btnIncreaseStock_Click(object sender, EventArgs e)
{
objPresenter.increaseStock();
}
protected void btnDecreaseStock_Click(object sender, EventArgs e)
{
objPresenter.decreaseStock();
}}

The simplest thing in the world the model

The model is pretty simple. It just increments and decrements the stock value through the two methods ‘IncrementStock’ and ‘DecrementStock’. It also has a ‘getStatus’ function which tells what is the stock level type i.e. over stocked, under stocked or optimally stocked. For simplicity we have defined the stock value as a static object.
public class Stock
{
public static int intStockValue;

public static void IncrementStock()
{
intStockValue++;
}
public static void DecrementStock()
{
intStockValue--;
}
public static int getStatus()
{
// if less than zero then -1
// if more than 5 then 1
// if in between 0
if (intStockValue > 5)
{
return 1;
}
else if (intStockValue < 0)
{
return -1;
}
else
{
return 0;
}

}}

The complete flow for the stock project

Below is a complete flow of the stock project from MVP perspective. The UI first hits the presenter. So all the events emitted from the UI will first route to the presenter. Presenter will use the model and then communicate back through the interface view. This interface view is the same interface by which your UI will inherit.

We have solved all the three problems with all the actions passing through the presenter the ASPX / Windows is completely decouple from the model. The presenter centralized the presentation logic and communicates through the interface. As the presentation logic is in a call we can reuse the logic.

As all the commands are passing through the presenter the UI is decoupled from the model. Now that we have all the components decoupled we can test the UI component separately using the presenter.

Reusing the presenter in windows

To just show how magical the presenter is. I have reused the same presentation logic in a windows application.

In the below sample we have ported the same presenter logic in a windows application.
private void Form1_Load(object sender, EventArgs e)
{
objpresenter.add(this);
}

private void btnInCreaseStock_Click(object sender, EventArgs e)
{
objpresenter.increaseStock();
}

private void btnDecreaseStock_Click(object sender, EventArgs e)
{
objpresenter.decreaseStock();
}

#region StockView Members

public void setStockValue(int intStockValue)
{
txtStockValue.Text = intStockValue.ToString();
}

public void setColor(Color objColor)
{
txtStockValue.BackColor = objColor;
}


The difference

You can understand the difference of how consuming the model objects directly and using a presenter varies. When we use the presenter we have moved the UI presentation logic to the presenter and also decoupled the model from the view.
Below is the code in which the UI directly uses the model…Lot of work right.

With presenter all the presentation logic is now centralized


Difference between MVC and MVP

The above figure summarizes the difference between MVP and MVC. We have just summarized the figure in tabular format below.

The project is coded from three aspects :-
• Using simple UI and Model perspective.
• Implementing MVP using WEB.
• Implementing MVP using windows.

The Web and windows samples are shown to show how we can reuse the presentation logic.
You can get the source code from here

Reference

No comments: