I have used Model View Presenter (MVP) a lot the last months. It's a great pattern, but a lot of the people I talk to have problem understanding how it works, and how to use it. I will try to explain it simple in this blog post.
Passive View and Supervising controller
The creator of MVP, Martin Fowler, spilt the pattern into to new patterns. This was due to apparent confusions between Model View Controller and MVP. The new patterns is called Passive View and Supervising Controller. The main difference between this to patterns, is that Passive View puts all the view update behavior in the controller/presenter and Supervising Controller encourage the view to do most of the updating itself, and only brings in the presenter/controller when there's more complex logic involved. In my example application later in this blog post, I show Passive View.
When to use it
MVP is a great pattern to ease up unit testing the graphical user interface (GUI), and to decouple the GUI from the underlying model. MVP makes switching GUI a breeze.
MVP is a pursuance of an other pattern called Model View Controller. In MVP, the view and the model don't know of each other, but in MVC the view knows of the model, and gets its updates from it.
I will cover MVC in a later post.
The figure below visually illustrates the pattern.
More thoroughgoing, this is what happens:
1) The user executes a action. The action is forwarded to the presenter.
2) The presenter asks the database (model) for the data to view.
3) The model sends the data back to the presenter.
4) The presenter updates the view with the new data.
There are normally four main classes used in the MVP pattern. To be more specific, three classes and a interface; the view, typical a WinForm, WebForm or XAML-file. The interface, witch describes the fields in the view. The presenter, witch executes the views actions and communicates with the model. And, of course, the underlying model, e.g. a database.
I have created an application witch displays name, e-mail, state, etc. The application uses the MVP pattern. This is what the application does: You enter a name into the search text box and the program reads information from a textfile. Information about the user is displayed in the form.
Shows the GUI in the application
The solution consists of three projects. One view, one presenter and one model. If you wanted to have several forms, you would have to create more presenters and views.
Shows the project structure
Let's look at the interface. It's found in the presenter project, and is named IPerson. It includes all the fields I want to display in the view.
The last field in the interface is Message. You will find it in the lower part of Form1, displaying: "Data fetched.". If any error occurs in the application, it's shown there. The class Form1 (Form1.cs), implements the interface.
Form1 implements all the properties in the interface. This is, as you know the startingpoint of the application. A instance of the presenter is created in the view. This way the presenter and view can communicate, and the presenter can update the GUI elements.
Shows some of the properties in Form1
When the search textbox is filled with a name, a event is triggered. It ends up in the method txtSearch_KeyUp in the class Form1:
The presenters constructor, inputs the view and the class fetching data from the model, as parameters. Hence, the presenter has access to the view and the model. This way of doing things is called Dependency Injection.
In the method UpdateData (called from the view), data is fetched from the datasource, and the view is filled with the returning data. If a exception occurs the field message, in the view, displays the error message. If nothing happens, the field displays "Data fetched.".
In the model (Data project), data is fetched from the file and put into a person object. Person object is returned to the presenter. If no data is found, an exception is thrown (witch is displayed in the message field in the GUI).
That is the course of events in the Model View Presenter pattern.
I recommend you to fire up Visual Studio and debug the sample application.
If you want to download the sourcecode for this example, you can find a link below.