.NET and me Coding dreams since 1998!

10Oct/0637

Model View Presenter (MVP) pattern

Update: The focus of this article is to describe the wiring between the presenter and view which are IMHO the most important thing to get for MVP pattern.
I deliberately melt down presenter and model (by having the presenter itself retrieving the user data in SetUpResultData method instead to call the separate UserRepository component) to avoid having additional service interface into the constructor pattern and making whole L100 example more complex. This is not OK outside of this example context and you shouldn't do it.
I have one more example explaining in more depth MVP pattern which you should read after this article which has more precise description


Introduction

MVP pattern is a type of UI design pattern which enables decoupling of the UI logic without UI representation and by that enables treating code base without consideration on presentation technology used.

One of the commonly stated advantages of this approach is that it enables writing of appropriate test scripts to test UI part of application. MVP enables that without the need of using third party tools which scripts user UI actions and which are fairly easy to use for testing simple actions like button click, but to write a user UI scripts for data manipulation of a grid or some more complex layout. All the logic is inside the presenter and the presenter is talking to view only through the interface, so any mock object could be used for testing as long it implements the view interface

Second advantage is the fact that by decoupling code in presenter level we are enabling reuse of the code logic to totally different presentation technologies. For the example, the same presenter can be used without any problem in both Web Form and Win Form worlds, as long as they implement agreed interface

Third advantage is in the fact that in big companies (like the one I'm working in) to implement your supportive UI code, you are often forced to wait on UX (user experience) people to make the web forms and that sometimes is a very long period. Also the way of communication between products, tech leads and developers is quite often based on some word document based FRD which (from developer perspective) is not the most precise way of specifying requirements. MVP is allowing the tech leads to crystallize results of an FRD to a set of interface definition of a view and that interface could be immediate base for developers to start coding , without waiting for anyone knowing very precise what are the requirements. (Who said TDD? :) )

Illustration 1. Logical view of the MVP pattern.

 

Short diagram description

View is responsible for visual representation of the form and it contains a presenter in private field. View is implementing interface whose members are approximated and technology striped UI elements of the view. When some event occurs on view is just forwarding it to presenter and it is presenter responsibility to handle the event. Presenter is manipulating view by talking to interface representation of the view. Presenter should never reference directly view members (UI controls). Presenter for his logic operations is using Model which can be persisted state or representation of the object which provides necessary functionality

Implementation procedure:

Create a view by using standard Visual Studio IDE tools.

For my example I will create first a web form with:

    • a label on top which would show possible validation error
    • Last name, first name, address and a city text boxes
    • Search text box with a button

Illustration 2. UI look of the view made by web form

Interface would be created in a separate project called presenter so we could reuse it later to demonstrate usage outside of our web application. Web application should have a reference to the presenter project

Illustration 3. Project structure  - separating and referencing presenter

Create a interface as an abstract form of a view with setters only for text boxes (because presenter would fill == set them) and getter property only for searcher (presenter would take that value and perform a search)

Illustration 4. View interface definition

namespace Presenter

{

    public interface IUserView

    {

        string FirstName { set;}

        string LastName { set;}

        string Address { set;}

        string City { set;}

        string ErrorMessage { set;}

        string SearchCriteria { get;}

    }

}

After creation of interface we are implementing it on view by setting and getting UI element values in the property

Illustration 5. View interface implementation

    #region IUserView Members

    public string FirstName

    {

        set { firstName.Text = value; }

    }

    public string LastName

    {

        set { lastName.Text = value; }

    }

    public string Address

    {

        set { address.Text = value; }

    }

    public string City

    {

        set { city.Text = value; }

    }

    public string ErrorMessage

    {

        set

        {

            errorMessageLabel.Text = value;

            errorMessageLabel.Visible = value != "";

        }

    }

    public string SearchCriteria

    {

        get { return searchCriteria.Text; }

    }

    #endregion


Creation of presenter class includes creation of a private field of view interface type and overloading of a constructor to accept that view interface

Illustration 6. Presenter  wiring the view

 namespace Presenter

{

    public class UserViewPresenter

    {

        IUserView _view;

        /// <summary>

        /// Initializes a new instance of the UserViewPresenter class.

        /// </summary>

        /// <param name="view"></param>

        public UserViewPresenter(IUserView view)

        {

            _view = view;

            SetCustomerData();

        }

Presenter would have to implement business logic, which In our example is finding of a customer for a given code. I’ve created Customer.xml file as D:Customer.XML

Illustration 7. Exampled data used for sample 

Presenter would implement therefore a method named SetCustomerData which task is to find a customer of a given code and update the view with resulting data. In case the entered code is not a valid number presenter would show appropriate message on validator that there is a syntax error. In case there are no contacts with a given code presenter should empty view and show a message that not existing code has been entered.

Illustration 8. Implementation of a presenter logic 

public void SetCustomerData()

{

int searchCode;

      bool isValid = int.TryParse

            (_view.SearchCriteria, out searchCode);

if (isValid)

      {

            using (DataSet ds = new DataSet())

            {

                  string filePath=string.Format(

"{0}Customers.xml",

AppDomain.CurrentDomain.BaseDirectory                   

                  );

ds.ReadXml(filePath);

                  ds.Tables[0].PrimaryKey

                        = new DataColumn[]

{ds.Tables[0].Columns["Code"]};

                        DataRow dr=

                            ds.Tables[0].Rows.Find

                            (_view.SearchCriteria);

if (dr != null)

                  {

                        _view.FirstName

                           = dr["FirstName"].ToString();

                        _view.LastName

                           = dr["LastName"].ToString();

                        _view.Address

                           = dr["Address"].ToString();

                        _view.City

                           = dr["City"].ToString();

                        _view.ErrorMessage

                           = "";

}

                  else

                  {

                        _view.FirstName = _view.LastName

                            = _view.Address = _view.City = "";

                        _view.ErrorMessage

                            = "Contact not existing";

}

}

}

      else

      {

            _view.FirstName = _view.LastName =

            _view.Address = _view.City = "";

            _view.ErrorMessage = "Not a valid code!!!";

}

}


Presenter would implement therefore a method named SetCustomerData which task is to find a customer of a given code and update the view with resulting data. In case the entered code is not a valid number presenter would show appropriate message on validator that there is a syntax error. In case there are no contacts with a given code presenter should empty view and show a message that not existing code has been entered.

Illustration 9. Results of an example - Code 1 entered - user shown

Illustration 10. Results of an example - Non existing valid code entered

 

Illustration 11. Results of an example - Invalid code entered

Now I will show reuse of the presenter for implementing the same logic in totally different technology: WinForm

I'll slightly change the look by switching the places between search criteria and the error message and city would be presented now by ComboList

Illustration 12. UI look of the view made by windows form

Usage of MVP patterns allows me just to implement view interface to win form and to view up presenter by passing to its constructor WinForm and all the same functionality is present without touching a presenter. That's why the presenter is speaking to interface which shouldn't be technology specific

Illustration 13. Wiring up the win form view to the presenter

using System.Windows.Forms;

using Presenter;

namespace WinForm

{

    public partial class UserViewForm : Form, IUserView

    {

        private UserViewPresenter _presenter;

        public UserViewForm()

        {

            InitializeComponent();

            _presenter = new UserViewPresenter(this);

            _presenter.SetCustomerData();

        }

       

        private void searchButton_Click(object sender, System.EventArgs e)

        {

            _presenter.SetCustomerData();

        }

        #region IUserView Implementation

                  // The same implementation like in WebForm case

                  // Wire up the control text properties to interface members

        #endregion

    }

}

 

So the complete solution would be something like:

Illustration 13. Complete project tree

And the result is the same functionality encapsulated in presenter is been reused for a win form

Illustration 14. Results of an example in win form - Existing code entered

Illustration 15. Results of an example in win form - Non existing code entered

Illustration 16. Results of an example in win form - Invalid code entered

Conclusion

MVP is very powerful UI design pattern which has multiple benefits for developing all kinds of user interfaces. That is the reason why CAB (Composite Application Block) is using it as a one of basic UI building principles 

Attachments

Source code of the MVP application used in this example  

 

Comments (37) Trackbacks (0)
  1. Best article I have read on the subject – nice1

  2. Well, I think you are combining the model with the presenter in your example. IMHO the logic of getting a costumer out of a xml file (or database or out of else where) doesn't belong to the responsiblity of the presenter but of the model.
    Also you are wiring the the presenter to the view within the view, thus making the the view depend on the presenter. Instead one might use another class (or even a DI-framwork) to inject the view into the presenter.
    just my 2cents…

  3. Tobsen,

    I do agree with the first comment but disagree with the second one 

    When I made the post I was more focused on the explaining the cooperation between the presenter and view on the most possible simple way and the way how presenter retrieves that data looked as a thing of side importance. But, you are right, presenter should delegate the call to the model (some service type or similar)

    Regarding the second part…

    The view up to the presenter is standard constructor type of DI pattern utilization for MVP pattern (I’m sure there are a lot of places which use the same c-tor DI thing)

    I don’t couple the presenter to the view (like you said), I couple the presenter with an interface of the view which means that any view implementing the view interface can work with the same presenter.

    I don’t find that type of "coupling" is bringing any problems so I deliberately applied “view make direct calls the presenter” and moved away from Fowler original implementation “view publish event which presenter subscribes for” as to complex to be used in real world applications

    I’m not sure what value would therefore bring another type injecting the view into the presenter, but I do know in case of the DI frameworks it would introduce unnecessary overkill of configuration files etc

  4. Well, I haven't worked that much with DI frameworks yet (I looked at Spring.Net and I know there is structure maps and I already downloaded Ninject…) so I can't tell if it is a "unnecessary overkill of configuration" for these frameworks. But I wonder how you actually test your UI-behaviour at all when you do it the way you described (e.g. instatiate the presenter in the view rather then injecting it).

    I also thought, before I read your comment, that it might be a good idea to be able to exchange the presenter if the need arises (a bug in the presenter has been fixed.. the logic of the presenter changed….) without recompiling the other parts (= the ui). I also thought that this is what DI-Frameworks can be used for.

    So maybe I am wrong and I won't even doubt that because I didn't do enough "real world applications" yet. So what I am going to do is l try to get an idea of what DI-Frameworks are made for and come back later to see if I have a better understanding of your procedure regarding the MVP pattern.
    regards tobsen.

  5. Very nice article!

    Small question – if you have to show another form after you do a search or after a user input – where is the best place to do it: in View or in Presenter?

    The simple example is Login form.

    I was thinking about having a function in IView called Redirect(string formName). The real redirect will be implemented in the view.

    In Asp.Net it will be simple redirect and in Forms it will be creating a new Form and making it active instead of current.

    What do you think?

    Thank you,

    Andrei Balan

  6. THIS IS A TOTAL WASTE OF TIME…

  7. Thanks alot .

  8. Thanks alot .

  9. I agree with tobson, the view becomes dependent to the presenter once you make a reference to it. I think the interfaces should be in a separate project. It will make the presenter unknown from the view and also the view from the presenter. Just an idea. I haven’t yet applied MVP on a project. I’m still researching on this pattern.

    Anyway good post.

  10. Diamond,

    you can get what you are recommending (view ignorant of concrete presenter) without the interfaces. All you need is view raising the event and presenter subscribing to that event..

    But, IMHO the key thing here is why view shouldn’t know about presenter? Presenter is not having any purpose other to support the view. In MVP relationship between View and Presenter is almost always 1-1. In other words, I’ve never felt the need to "switch" different view presenters during the runtime

    Every abstraction comes with a cost of decreased readability. That’s why my personal opinion is that you should not add layers of indirection in case there is no "problem" which would be solved by that. Not following that principle IMHO leads to over-architected solutions

  11. Andrei,

    I’ve seen couple of times having IView.RedirectTo(string) and in general it is perfectly fine solution for most use case scenarios.

    Anyhow, I am just about to start MVP blog post series where one of the post would cover making of IHttpContextService which would provide to Presenter access to Redirect, Session, Cookies etc without th need of referencing System.Web into presenter assembly so this could maybe give you another idea on how to do this directly from presenter without the need to add any helpers to view

  12. re: how to test it when not injected

    Tobsen,

    the key point here is that you are testing only presenter and not the view. What happens in the view, you don’t care. You can test presenter even not having at all view.

    To test the presenter (in thise example) you would mock the IView to represent appropriate context state needed for test and you would test only presenter methods.

    I would be covering this in more details in my upcoming MVP blog post series, but until then check out this post which have illustration on how to test MVP with rhino mocks

    blog.vuscode.com/…/tdd-rhino-mocks-part-1-introduction.aspx

  13. About Illustration 5. View interface implementation, in which class i should we write the #region code and how it is associated with Customer.XML?

  14. malovicn,

    cud u please throw some more light on making view ignorant of concrete presenter.

    how would present subscribe to events raised by the view?

    thanks

  15. JobLot,

    if I understand you correctly what are you asking then check my other MVP example  which shows how view can raise an event instead of direct call to presenter method

    blog.vuscode.com/…/model-view-presenter-mvp-design-pattern-close-look-part-1-passive-view.aspx

  16. Krishna,

    at the bottom of the post (Attachments) you have source code which you can checkout

    (The code goes to UserView.aspx.cs)

  17. Hi Malovic,

                    Thanks for your simple, but helpful article about MVP pattern. Your article help me to understand MVP in a short time. Thanks again.

    Shahriar Hasan Sayed

  18. Very nice article indeed. simple and sweet

  19. Very nice article.

    Please keep it on.

  20. very nice basic article

  21. Hi Nikola,

    Firstly this is  a very simple cool illustration for MVP design pattern , thanks for that

    Secondly I want to ask some questions as I’m new to this paradigm

                  – Why should I use Interfaces between layers instead of

                    directly referencing that Layer ?

                    i.e Presenter p= new Presenter(); //in the view layer

                 - If i should use Interfaces so how to determine its’

                   members in advance ?

    and Thanks again for that demonstration that helped me alot in understanding this design pattern

    (note: I’ve some experience in 3 layers architecture and I just reference the layer directly without an interface )

  22. Good post.

    But I don’t think that view needs to know anything about presenter. The responsibility of view is dealing with UI logic. If the button is clicked in a view, all view needs to do is firing a event to tell other objects who are interested in the click event. If the presenter is part of the view, the view cannot be used by other presenter. RIght?

  23. Keping:

    I thing that in MVP all events should be handle in Presenter rather than in the View. To use another presenters in the Presenter should be Interfece. (but I don’t think you could want to change Presenter at all).

  24. Keping,

    The “fire event” way you are describing is how this pattern is described by Fowler and if you check out the blog.vuscode.com/…/model-view-presenter-mvp-design-pattern-close-look-part-1-passive-view.aspx you’ll see there example of such approach.

    The problem I had with this implementation is that it is (IMHO) overkill introducing the level of abstraction where it is not needed.

    You said: the view would fire an event and other object interested in event would just subscribe to it.

    My question to you: what would be that other object if it won’t be the presenter?

    Changing the presenters is also an argument often mentioned but in MVP (contrary to MVC) a view usually has only one presenter and a presenter is usually used only for one view.

    That’s way I prefer in my personal MVP development simply to call _presenter.SomeMethod() from code behind event handler

    IMHO, the role of presenter is just to be “TDD friendly code behind” and the simplest possible way to do that is the best way,

    Off course, all this been said is my personal preference and I am not claiming it is fitting everyone use case :)

    HTH,

    Nikola

  25. Kamil,

    if the idea behind having events in Presenter is to allow view to send signal to presenter about activity then having events in a Presenter is not making a lot of sense to me because (in order to subscribe to them) the view would have to reference presenter.

    Once the presenter is referenced, it is much easier for view just to call presenter method then to subscribe to his events.

    If the idea behind presenter having events is that presenter would send signals to view (direct the view behavior) then I don’t think it is MVP any more because in MVP presenter access the view directlly through its abstraction (view interface).

    It looks much mor eto me as an event driven architecture kind a thing which I am not sure how much overkill it would be in case of web development but I would really like to see some code example :)

    Nikola

  26. Mina Saad,

    If you would choose to use instead of view interface directly the view (web page) then in your presenter you would have to reference system.web, instead of setting as string you would have to work with UI control properties etc.

    In other words, you would end with standard code behind aspx.cs file in a separate class which could be a lot of work for nothing.

    The main reason why you would use view interface is because it enables your presenter code to be totally ignorant about UI elements, so implementing presenter logic and writing tests should be much easier and not dependable on UI elements (labels, text boxes etc)

    Writing a test for presenter would give you the answer and I encourage you to change the sample the way you like and then to write unit test for it. You can then compare that with test given here blog.vuscode.com/…/tdd-rhino-mocks-part-1-introduction.aspx

    As for how to determine what needs to be on interface, that depends on what flavor of MVP pattern you want to use (passive view or supervising controller)

    In case of passive view you can do something like this:

    -Text box -> DateTime {get; set;

    -Label -> DateTime {set;}

    -Calendar,DatePicker DateTime {get;set}

    -DataGrid, DataRepeater etc – IEnumerable<T> {set;}

    -DropDownList.DataSource- IEnumerable<T> {set;}

    -DropDownList.SelectedIndex – int {get; set;}

    -Etc…

    HTH,

    Nikola

  27. Nikola,

    My first read on your blog entry (eventhough I think I have seen it in the past) and this article really helpful in making me understand the MVP model.

    Looking forward to read your great articles.

    -Mike

  28. Hi Malovicn,

    Thank you for your post, as a matter of code analysis we can not use code in properties (properties should not have operations) but in the MVP pattern, the presenter sets the properties of view which may be Datasource, etc and needs some operations in view.

    IEnumerable<T> View.GridData

    {

    set

    {

    binding operations // not proper for property

    }

    thank yoy in advance

  29. Thank you for the this post and all the comments. I have a question regarding a view that is composed of other user controls. Would each UC would have it’s own presenter? I have tried using this pattern but the problem I run into is that it got very messy with complex view and ones that included other UC.

  30. Thanks a lot man

  31. Wow! this is what I am expecting!

  32. hi thanks for the example … but as i am a .net person and currently working on java and we are using GWT+MVP, so can any body show me example like above in java GWT

    or if anybody can provide me the link for the same , it would be of gre8 help.

    thanks alot

  33. Clear Explanation with good sample…Thanks for sharing the knowledge

  34. Check the MVC# at http://www.mvcsharp.org

    It's excellent example of the model-view-presenter implementation for WinForms, WebForms and Silverlight. Unfortunately it's abandoned, but very mature and stable.

  35. Malovic

    Excellent article with very helpful practical pointers.   I did apply this pointers in my GWT/GXT based Web UI and it worked very well. I didn't use Event based model but let view directly call presenter (it has reference of it) for all user interactions on various widgets/controls.

    Thanks again and keep up the great work. BTW, I am Java person but still your .net example was very valuable.

    - Mahesh

  36. hi i want to know if you have one example of MVP but with access to data base? thank you ;)

  37. Very nice article.

    I have a question here. I currently start working on a win form application with MVP pattern.

    In my applcation, I have a main form. There are several buttons on it. Like add new customer, search a custome, make a order, etc.

    For the main form, I created a presenter and a view interface. Question is that when user click on Creating New customer button, the code for creating new customer form should be in the presenter or in the MainForm.cs?

    If the code is in the presenter, that means the presenters project needs a reference to Form project.

    But if the creating form code is in the MianForm.cs, that means I write  the business logic in the view.

    An even more complicated scenario is user in the Search customer form found a customer, and a customer details displayed in a form, and then need creates an order form while the customer details form should still displayed. these form creating codes should be in the form.cs or different presenters?

    So what is the correct way to do it?

    Thanks.


Leave a comment

No trackbacks yet.