Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Model View Presenter

4.68/5 (35 votes)
3 Mar 2009CPOL9 min read 168.6K   1.8K  
Understand MVP, execute a sample project with MVP, and implement the same using a Windows UI.

Table of contents

Introduction and goal

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

Pre-requisites

This article assumes you know MVC; in case you do not, you can read about it at 3Musketeers.aspx.

The simple stock project

The best way to understand any architectural concept is by taking a small practical sample and then applying the 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, we can have three status: overstocked, under stocked, or optimally stocked.

Image 1

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

Stock value Color
Value is between 1 and 5 (optimally stocked) Green color
Value is above 5 (overstock) Blue color
Value is less than zero (under stocked) Red color

Analyzing the project

What we will do is define the problem logic in two parts:

  • Presentation logic
  • Business logic
Business logic will be handled by the business object Presentation logic will ne handled in the ASPX or Windows form
Receive the events from the presentation and maintain the stock value accordingly. In short, increment and decrement the stock value. Trigger the events increment stock and decrement stock. The events will be triggered when the user clicks the increase stock button or the decrement stock button.
Depending on the value of the stock, determine the three states: under stocked, overstocked, or optimally stocked. <o>Depending on the state of the stock, change the visual colors:

 

  • Under stocked changes to RED.
  • Over stocked changes to blue.
  • Optimally stocked changes to green.

The other responsibilities look fine, so let’s concentrate on the last responsibility 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 a slight concern when we look at the presentation logic.

We have three big problems:

Reuse of the 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 a Windows app. As we have the presentation logic tied up in the UI code, it will be difficult to decouple it from the UI. We also would like to use the same presentation logic with other pages of the same type.

Presentation is tied up with the business object

The presentation is tied up with the business object. It’s doing a 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 them. MVP will help us easily solve the above three problems.

Problem 1: Reuse of the presentation logic

If we want to reuse the presentation logic irrespective of the UI type, we need to move this logic to a 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 a 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 through the view interface. This way, the model is never in touch with the concrete UI, i.e., the ASPX or Windows interface. All user interfaces should implement this interface so that the presenter can communicate with the UI in a decoupled manner.

Image 2

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

Implementing MVP in the stock project

The view interface and the presenter of the stock project

We will first visualize how the UI will look like. There will be two buttons, one which increments the stock value and the other which decrements the stock value. The stock value is displayed on the stock text box and the color is set according to the value of the stock.

Image 3

All events are first sent to the presenter. So all the events need 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 the presenter can communicate using the same.

Shown below is the interface for the ASPX page. We need the stock value so we have defined a method called setStockValue and we also need the color, so we have defined a method called setColor.

C#
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.

C#
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.

C#
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.

C#
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 an ASPX page or a Windows form, 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 it has received from the model.

C#
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 the buttons, we have called the increaseStock and DecreaseStock methods of the presenter.

C#
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 us the stock level type: over stocked, under stocked, or optimally stocked. For simplicity, we have defined the stock value as a static object.

C#
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 an MVP perspective. The UI first hits the presenter. So all the events emitted from the UI will first route to the presenter. The presenter will use the model and then communicate back through the interface view. This interface view is the same interface which your UI will inherit.

Image 4

We have solved all the three problems with all the actions passing through the presenter; the ASPX page/ Windows form is completely decoupled from the model. The presenter centralizes 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 a Windows app

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

Image 5

In the below sample, we have ported the same presenter logic in a Windows application:

C#
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?

Image 6

With the presenter, all the presentation logic is now centralized:

Image 7

Differences between MVC and MVP

Image 8

The above figure summarizes the differences between MVP and MVC. We will summarize the figure in tabular format below.

MVP MVC
In MVP, the view and the model are completely decoupled. In MVC, the view and model are not completely decoupled.
In MVP, the presenter handles all the UI events. In MVC, the view handles the events.
In MVP, the presenter calls back to update the view via the view interface. In MVC, the controller passes the model to the view and the view then updates itself.

Download the code

You can download the stock project from this link: click here. The project is coded from three aspects:

  • Using a simple UI and Model perspective.
  • Implementing MVP using WEB.
  • Implementing MVP using Windows.

The Web and Windows samples are shown to illustrate how we can reuse the presentation logic.

References

It would be selfish to say that all the above knowledge is mine. Below are some links which I have referred to while I was writing this article:

For further reading do watch the below interview preparation videos and step by step video series.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)