Model View Presenter Part I – Building it from Scratch

by Rod 3/31/2008 11:13:00 PM

MVP Part I Sample.zip (83.87 kb)


Introduction

The advantages of knowing Model-View-Presenter (MVP) pattern from scratch: 

  • Engineer’s knowledge can be applied across different OOP languages (like VB.NET, Ruby, Java, C#). This is advantageous for developers and architects working on different types of languages.
  • Engineer’s knowledge can be applied across different versions of IDE and frameworks.
  • Engineer becomes versatile and mobile across different platforms and languages.
  • Engineer will not be dependent to MVP tools.

MVP Tools are not bad, the downside of using tools is that they are often tied up to IDE versions and often does not support older versions. Tools have limited support on languages and frameworks, so if the engineer is given a project that does not support his beloved tool he’ll go back to square one or worst he will blame the tool or start cursing the client/boss who gave the project… hehehe…

The goals of MVP are:

  • Testability of the application
  • Cohesion or separation of responsibility
  • Orthogonality

Orthogonality is the ability to change the conceptual design of the application with minimal impact to the entire application. Domino effect is common to two-tier application where a slight change to data access layer affects the presentation and the business process.

Advantages of MVP:

  • Parallel development. Separation of responsibilities of UI developer, business logic developer, and data access developer that make them work independently. In economics, it’s division of labor.
  • Reusability. Reuse presenter in different user interface designs (web, windows form, etc). I even use it in Visual Studio Tools for Office (VSTO) application.
  • Maintainability due to clear separation of responsibilities (UI, application behavior, and domain).
  • User Interface independent. This is an advantage for an application that supports different user interface types.

Let’s get it on!

Download the code and launch your Visual Studio .NET and open the MVPSession.sln file.

Note: The sample is built using Visual Studio 2005 and compatible with VS 2008. If you are running Visual Studio 2003 just change the IList<T> types to IList. I already included the assemblies we need for Mocking (NMock) and Unit Testing (NUnit).

To illustrate the advantages I mentioned above, I created a sample application that will insert new employee profile. This will show how MVP will be reused and consumed by two different user interface types with minimal impact or without impact at all to the presentation logic. It will also shows how to separate the presentation from the presentation logic.

A Tester module is also added to show how to create a mock tester. Mock testing is also known as Horizontal Testing whose main goal is to test the behavior of the application without going deeply to the business logic and data access layer. We will discuss more about mocking in MVP Part II.

Figure 1 shows the architecture reference of the sample application –  User Interface Layer (Presentation and Presentation Logic), Business Logic, and the Data Access Layer. In this article we will just focus only on the User Interface Layer and how to test it.

Figure 1. Sample Application Architecture

Presentation is the layer where the user interacts with the application and can be represented in many types of interfaces - mobile, web, windows forms, etc. In our sample application, we only use Windows Form and Web Form.

Presentation Logic houses the behavior or the UI logic of the view. In most cases, it requires at least a view and a model in order for the presenter to work. Service layer is sometimes optional if you don’t have data to pull from data sources (database, file, or web service). I sometimes call this the MVP layer.

Parts of the Presentation Logic:

  • View is best described as the logical representation of the UI and provides an interface for the presenter to communicate with the UI.
  • Presenter houses the behavior and UI logic.
  • Model is just an object that represents the module or the view. It’s an ideal place to put the validation and small business rules like computation of total amount or formulas. This just a lump of data that holds the state and data of the view. In the sample application, our model is the EmployeeModel object. In an ordering system, the model would be the Order object that contains order details and order items.
  • Service is a data provider and a façade that manages data retrieval from different data sources (database, web service, xml, etc). It can also house some business logic and validation. It is not aware of the user interface type (whether it is a web, mobile, or windows form). In the sample application, our service layer only returns dummy data. If you have time, you can play with it by adding the BLL and/or DAL layer.

Side Note:
As a rule of thumb, do not include any UI libraries in your Presentation or MVP project like System.Web or System.Windows.Forms to avoid UI objects from mixing with the presenter code. This will make your presenter less flexible.

In the diagram above you can see that Model has no direct access to Service and only the presenter has direct access to both. But it does not mean that Model cannot access the Service. In most of my application I do not give Model access to Service as much as possible to centralize all the behavior and logic in the presenter and make Model just a lump data. This makes the application easy to debug and test.
 
To start the implementation, let’s assume that we have four engineers – Leo, Richard, Ryan, and Chris. Leo is a Windows Form UI designer, Richard is a UI/Presentation Developer, Ryan is the backend developer, and Chris is the Architect.

Chris was given a project to create a data entry application for HR. Chris decided to design the application in MVP pattern for agile development and to let engineer work in parallel. Chris divided the project into three parts the UI Interface Layer – Business Logic Layer – Data Access Layer and distributed the task to the four engineers.

Leo as a UI designer doesn’t care about how the data will be processed or how the form will behave when Submit button is clicked. He only cares about how the data will be presented to the user and how to make the application user friendly to the users. So he created the form in Figure 2.

Figure 2. Windows Forms UI.

Richard as a Presentation developer doesn’t care about what control to use in each fields, what color of the error message and labels are, and what the UI type is, whether it is a windows forms or a web form. He only cares about the fields needed and its data type, what are the required fields, validation rules, business flow, and the service provider. So he created IEmployeeView, IEmployee and EmployeeModel, EmployeeService, and EmployeePresenter objects. See MVP project for the implementation.

Ryan as a backend developer doesn’t care about the the presentation. He only cares about how to provide the client or consumer with the data, where to fetch the data, how to connect to the database, and how to ensure the integrity and consistency of data. In our sample application we don’t have the BLL and DAL project yet, so just assume that Ryan is still working on it or probably sick. Hehehe... We hope Ryan is finished with the DAL and/or BLL by the time MVP Part II article is ready.

Question: Do Richard requires to integrate his work to the UI and backend code before he can test the behavior and flow?

Answer: No.  Richard could proceed testing his work without the UI and backend. This method of testing is called Mock testing or Horizontal Testing. While Leo and Ryan are busy working on the UI and backend, Richard can proceed creating a Mock tester project to test his work. See Test project in the sample solution. In this sample we are using NMock for mock testing.

Late in the game, Marvin the Project Manager decided to add a Web form UI that will be used by the global HR in the main headquarters. So he added Jen as a resource to design HTML Forms. Jen created the form in Figure 3.

Figure 3. Web Form

Question: Are we going to create a new Presenter for the new web form UI?

Answer: No, we can reuse existing presentation with minor changes. Just take note that web is stateless so we need to modify interfaces that are statefull like the dialog boxes to display error messages.

Three months have pasts. Marvin comes in and approaches the team and says “Guys we did a great job, the project was so great that attracts another client. He likes the system and just wants to change the Salary Range dropdown to list box and wants to connect to his company database through web service.” Chris the architect evaluated and says “all we need to do is to modify the Service and the Form”. So the tasks are assigned to Leo and Richard.

Leo will just change comboxSalary to listBoxSalary in the form.

Richard will just create a new Service class that inherits the IEmployeeService and change the service used by the presenter in the Form_Load with the new service object named EmployeeWebService.

See WinUI2 project for the fixes made by leo and richard. In EmployeeWebService, I just provide a dummy data for the application to run. You can play with it with real web service if you have time.

How to Integrate Presentation to UI

 

Integrating presentation to UI is just three easy steps away:

 

   1. Inherit the view interface to UI. In our example its IEmployeeView interface.

      

public partial class FormEmployee : Form, IEmployeeView

      {  ...

}

   2. Implement all the IEmployeeView interfaces by providing code to each of the interfaces. See FormEmployee.  

   3. Initialize the presenter in Form_Load.

          _presenter.Initialize();

        

How to Run the Test Project

 

There are several ways and tools to run the test project.

 


Running Test Project Using Resharper (http://www.jetbrains.com/resharper/) 

 

If you have Resharper you can just simply click the bubble besides the test case and select the Run From Tester context menu. This will launch the Unit Test Runner within your IDE.

 

Figure 4.0. Running Test using Resharper.

 

 

Figure 4.1. Unit Test Runner.

 

Running Test Project Using NUnit (http://www.nunit.org/) 

1. Run the NUnit GUI.
2. Drag and Drop Test.dll found in Test project’s bin to NUnit GUI. You can also use the File | Open Project, and then browse the Test.dll.
3. Then click Run button.

Figure 4.3. NUnit GUI

 

Running Test Project using TestDriven.NET (http://www.testdriven.net/)

If you have TestDriven.NET installed you can just right click the Test project, then select the Test With from the context menu and select one of the variety of test tools supported. If you select NUnit it will launch NUnit GUI.

For a quick test you can just select the Run Test(s) from the context menu.

Figure 4.4. TestDriven.NET Context Menu

The cases above shows

  • Division of labor
  • Productivity and Efficiency
  • Maintainability of the application
  • Orthogonality 
  • Testability

There are times when you are developing your MVP application you’ll encounter a sort of dead end where you develop a presentation that it’s hard to test. If you are in this situation just refactor your code and remember the law of cohesion. Sometimes your code gets tangled because of lack of cohesion.

May the force be with you.
Rod

Currently rated 5.0 by 8 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , ,

Architectures | MVP | TDD

Related posts

Comments

4/1/2008 12:56:21 PM

Marvin

nice blog. very informative . =)

Marvin ph

4/1/2008 12:57:47 PM

Chris Ongsuco

At last! Nice one Rod. Keep it up.

Chris Ongsuco ph

4/1/2008 2:12:41 PM

Richard

I've been looking all around the net reading and studying about MVP but just gave me more confusions about it. With this article i understand clearly now the power of MVP!..

Richard ph

4/1/2008 2:27:33 PM

fredie savellano

Great!

fredie savellano ph

4/1/2008 4:47:19 PM

pingback

Pingback from ryangaraygay.com

Model View Presenter - Building from Scratch

ryangaraygay.com

4/1/2008 4:47:31 PM

Ryan Garaygay

Can't wait for Part II Laughing

Ryan Garaygay ph

4/2/2008 7:45:11 PM

Rod Fornillos IV

wow, this is really helpful and informative! i will be waiting for the next part...

Rod Fornillos IV ph

4/3/2008 1:12:13 AM

Rodel Dagumampan

Great article Rod. Keep them coming!

Rodel Dagumampan ph

4/4/2008 7:42:11 AM

andre

galing! Smile

andre sg

4/10/2008 6:42:04 AM

Marvin

In keeping with the Rods tradition of using real world case to explain things , Im going to make use of the same approach to ask questions (hehehe).

After discussion with the engineers , the dreaded QA Specialist , Aileen , comes into view and made this intriguing comment : " I like the way you implement the project but Im not satisfied with the way you handle security . Can you put a login screen for your app so that only authenticated users are allowed to use it?". So Chris , who wanted to go home already and eat chicken with lots of hot sauce , went back to the drawing board to come up with a solution.

Question: If a new Login UI is to be created , does it mean a new model-view-presenter is to be created for the Login task (ILoginView,ILogin,Login,LoginPresenter,LoginService)?

Question: If late in the game , Mac a McDo representative who is also a Monk , wants to use the software and requires several new features that would require new models,views and presenters (assuming the answer to question 1 is Yes) , will all these be placed in the MVP project? How will you make the project more manageable , creating several folders inside the MVP to seperate the different entities (model, view,presenter,service) or create separate Model project, View Project, Presenter Project , service Project ? Or perhaps there is a better and sexier way to do it.

Marvin ph

4/10/2008 11:09:37 AM

Leo Camalig

This is why I want to be like Rod...
Your the best parin....

Leo Camalig ph

4/10/2008 8:58:42 PM

Rod

Same cast of characters pa rin pare.. hehehe...

Thanks guys! your comments inspire me to continue sharing my knowledge... I already started part II.. keep you posted...

Rod

4/10/2008 9:26:51 PM

Rod

Hi Marvin,

Thanks for the feedback I really appreciate it.

Question 1: Yes, for small screens like login, you can use passive view. In passive view, the view is as dumb as we can possibly make it.

Question 2: There is no rule in MVP that 1 View = 1 Presenter. You can pass one or more view to a single presenter. If the views are all related you can use one presenter. Say in my current project I created a simulator that uses 3 complex controls where I created each control a view (IControlView1, etc..) and pass it to single presenter object that manipulate this views. Remember views is just a logical representation of your presentation. Remember law of cohesion.

As to the project, the answer is it depends, if McDo changes just extend the functinality of login by adding remember me or forgot password this can easily be integrated by inheritance or just simply adding new interfaces in your view. If the changes is more on the flow say what would be ne page to display if the password is invalid, etc.. this changes can be placed in the presenter.

As to organizing the project, you can group your MVP objects by creating a folder and group it by module. Say:

Root
|----- Inventory
|-- OrderModel.cs
|-- InventoryPresenter.cs
|-- InventoryService.cs

In my project I usually remove the extra Inventory namespace in OrderModel.cs, InvenotryPresenter.cs, and InventoryService.cs that way when you add the assembly you have access to all of your MVP libraries.

Also I place interfaces in my common project. that way you can use it in testing project, BLL, and DAL and to avoid cyclic reference.

Rod

4/11/2008 1:55:18 PM

Stepen Chow

Great!

Stepen Chow zw

4/17/2008 2:00:29 AM

Ben

Right on! Subscribed!!!

Ben us

4/19/2008 11:50:43 PM

kerwin

heheheheh... grabe ah ... believe na gid kmi ah ....

kerwin ph

6/14/2008 3:28:41 AM

Richard

Nice post! I noticed your EmployeeForm View class seems a bit broken in the MVP sense since it creates the EmployeePresenter.
I'm new to MVP at the moment, but thinking about this, I would probably use an ApplicationPresenter, and call Application.Run with an ApplicationContext object.
Would be keen to hear other suggestions! Thanks.

Richard gb

6/18/2008 10:01:05 PM

Rod

Hi Richard,

If we use the presenter as a launcher or context holder (ApplicationPresenter) it will defeat the purpose of the MVP pattern. MVP is often a triad - View which is the logical representation, Model as a state holder, and Presenter as the business logic or UI logic. The difference of MVP to normal 3 layer application is that we devide the presentation layer into MVP for cohesion, orthogonality, and testability of the application.

The name EmployeePresenter is just my naming convention where I use the model as the prefix(XXXPresenter). If i have an invoice form I named it InvoicePresenter, IInvoiceEntity, IInvoiceService where Invoice is the model or domain. This is to avoid confusion. for larger project I create a folder for each MVP objects that way it will nat clutter.

Thanks for your comments!
Rod

Rod

6/22/2008 7:42:28 AM

Ajit Singh

Great article and thanks a lot for the excellent accompanying code. Eagerly waiting for MVP Part 2 related to Mock Testing. Keep it up.

Ajit Singh in

7/24/2008 9:33:53 AM

Rajasekaran Moorthy

Great article.

Rajasekaran Moorthy in

8/1/2008 8:07:23 PM

Kay

Very good. Is there a VB.net version?

Kay us

8/4/2008 6:21:29 PM

Rod

Hi Guys,

Thanks for your comments. I'm still working on the part 2. Sorry about the delay, I was busy this past couple of months meeting with the client and organizing our team.

Hi Kay,

you can find online convertion tools that will help you convert the code to VB.NET. here are some of the site I found.

labs.developerfusion.co.uk/.../csharp-to-vb.aspx
http://www.kamalpatel.net/ConvertCSharp2VB.aspx

Regards,
Rod

Rod ph

8/9/2008 9:00:57 PM

Leon

great article! waiting for part 2 :-P

Leon ph

8/20/2008 5:54:59 AM

Pleb

great article,

I keep your sample project open on another monitor and use it for reference.

Any chance of expanding out the example and building the other layers? Maybe throw a few known gotcha's in too? I'd like to see how this is done, as I seem to get stuck at this step.

Pleb au

8/20/2008 11:29:25 PM

Alex

Great article! I have a question for you. I am building an application and have adopted the MVP pattern but am a bit stuck on one thing. Part of my application processes text files and my Business Object layer determines if a particular text file has already be imported and if so, I want to be able to ask the user if they want to overwrite the old with the new. If so, I want to process the file as usual but first deleting the old records. if I return to the presenter with a code that says "ask the user" who owns the creation of that message box? I don't think it should live in the presenter but I am not sure how to hook it up so that the view will display the message box and return that value back to the point in the presenter than needs the result to continue. Hope this makes a bit of sense.

Thanks for your time!
Alex

Alex us

8/21/2008 12:17:16 AM

Test

Hi Pleb,

I'll include your request in Part 2 of the article.

Hi Alex,

You are right, the owner of the creation of the Message Box is the Presentation or View, NOT the presenter. Rule of thumb - do not add reference to UI libraries in your presenter (UI libraries are System.Web, System.Windows.Forms, etc.. ).

Here is how to do it.

1. Create a view that contains the interface that will handle the delete confirmation. If you have existing view, just add it.

public interface IMyView
{
...
bool ConfirmDelete();
...
}

2. On your Presentation/View or Form add the implementation of the ConfirmDelete(). This is where the Messagebox is created.


public class MyForm: Form, IMyView
{
...
public bool ConfirmDelete()
{
return MessageBox("Overwrite?", ...) == DialogResult.Yes;
}
...

private void buttonProcessText_Click(object sender, EventArgs e)
{
_presenter.ProcessTextFile();
}
}

3. Then in your presenter you need to code the presenation logic.

public class MyPresenter
{
...

public MyPresenter(IMyView view)
{
_view = view;
}

...

public void ProcessTextFile()
{
...
if(_view.ConfirmDelete())
{
//-- DELETE FILE CODE GOES HERE
}

else
{
//-- DO NOT DELETE FILE CODE GOES HERE
}
...
}

...

}

Hope this answers your questions.

Test

8/21/2008 4:43:47 PM

Alex

Thanks! I appreciate your help.

Alex us

8/25/2008 3:21:38 AM

Jay

Nice one Rod. Very helpful and informative. I'm currently working with Model-View-Presenter and also SCS or Smart Client Shell..... Teach me Master! I want to be your padawan LOL. Laughing

Jay au

10/21/2008 1:26:10 PM

Rod

Part II is now published. See www.cerquit.com/.../...Part-II---Unit-Testing.aspx

Rock On!
Rod

Rod

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

11/21/2008 2:56:44 PM

Powered by BlogEngine.NET 1.3.0.0
Theme by Mads Kristensen

About the author

Name of author Rod Cerrada
One way to enrich world's treasure is to share your knowledge to younger generations.

E-mail me Send mail


Pages

    Calendar

    <<  November 2008  >>
    MoTuWeThFrSaSu
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    View posts in large calendar

    Recent comments

    Authors





    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2008

    Sign in