Introduction
Part 23 of this series of articles described the basic Model-View-Presenter pattern (MVP).
This article examines the Model-View-Presenter pattern in more detail. It describes some variations on the basic pattern, and looks at the advantages and disadvantages of using the pattern.
Part 25 of this series of articles will examine how the Model-View-Controller pattern is implemented in the Smart Client Software Factory (SCSF).
Can the View Update Itself? Active View versus Passive View
The version of Model-View-Presenter described in part 23 has an ‘active View’. This means that the View can update itself directly from the Model (arrows C and D on the diagram in the article). As described in part 23, the View can also be updated by the Presenter.
An alternative to this is what Martin Fowler calls the ‘passive View’. Here the View cannot update itself directly from the Model. The only way the View can be updated is via the Presenter. This is the pattern that the Microsoft SCSF documentation describes as Model-View-Presenter.
Diagrammatically this looks as below. It’s identical to the diagram in part 23 except that there are no arrows between the Model and the View:
The passive View design leads to more code in the Presenter and more code in general as the View now has to expose everything that can be updated on its interface, and the Presenter has to be coded to update it appropriately. However, this is arguably a less complicated design than the original active View in part 23.
Does the View Update Automatically? Active Model-View-Presenter versus Passive Model-View-Presenter
As with Model-View-Controller we have a distinction between an ‘active’ and a ‘passive’ design overall (see the section ‘Active and Passive MVC’ in part 22). Model-View-Presenter as described above in part 23 is ‘active’ Model-View-Presenter. This means that if the Model changes all Views will be updated automatically via the eventing mechanism. These events may be sunk in the Presenter or the View.
It is also possible to set up ‘passive’ Model-View-Presenter. This is a slightly simpler pattern where the Model does not raise an event when it changes. This means the View is not updated ‘automatically’. Instead the View is updated when the user next requests it (by pressing a ‘Refresh’ button for instance). At this time either the View or the Presenter will go to the Model to get the new data.
Advantages of Model-View-Presenter
As with Model-View-Controller, Model-View-Presenter has the advantage that it clarifies the structure of our user interface code and can make it easier to maintain. Not only do we have our data taken out of the View and put into the Model, but also almost all complex screen logic will now reside in the Presenter.
This solves the problems with more traditional user interface designs as described in the last few articles. However, it comes at the cost of some complexity.
Since we now have almost no code in our View apart from screen drawing code Model-View-Presenter also makes it theoretically much easier to replace user interface components (user controls, whole screens, or even the whole user interface (Windows Forms to WPF for example)).
In addition unit testing the user interface becomes much easier as we can test the logic by just testing the Presenter. However see part 23 for some comments on whether this is strictly necessary.
Disadvantages of Model-View-Presenter
The disadvantages of Model-View-Presenter are similar to the disadvantages of Model-View-Controller as described in part 22:
- The pattern is complex and may be unnecessary for simple screens.
- The pattern is one more thing to learn for busy developers: there’s some overhead.
- It can be hard to debug events being fired in active Model-View-Presenter.
- The ‘Passive View’ version of Model-View-Presenter can lead to a certain amount of boilerplate code having to be written to get the interface into the View to work.
My personal view is that even if you think this is a useful pattern (and it is) you shouldn’t use it indiscriminately on every screen in your application. You should use it where you have reasonably complex logic which will benefit from splitting the user interface classes in this way.
User Events and View Logic Combined in the Presenter
One thing that seems a bit odd with Model-View-Presenter is that we have factored both the responses to user input events and what I’m calling the ‘complex view logic’ into our Presenter. At first glance these seem to be slightly different things: perhaps we should have separate classes for each? Perhaps we need a Presenter and a Controller?
One reason for not doing this is that our user interface is getting very complicated if we have both Presenter and Controller.
Also, in the passive version of Model-View-Presenter we may want the user event itself to call the complex view logic and to directly update the View. This means that the code to handle the user event also needs to contain the view logic. It can’t do this if we have separate classes for the two pieces of functionality. In this case it makes more sense if we only have one class.
However, splitting the Presenter into two classes may be a valid pattern in active Model-View-Presenter. Here the Model will be updated in response to a user event by the Presenter. The Model will then raise an event to the Presenters telling them to update the View for complex view logic. The user event and complex view logic are thus separate in the Presenter and could be split into separate classes. We would probably only want to do this in very complex screens.
Model-View-Controller and Model-View-Presenter Confusion
As Martin Fowler points out, there’s a lot of confusion over what Model-View-Controller is. As already discussed, this arises because it doesn’t really apply to modern user interface programming languages in its purest Smalltalk form.
Equally there seems to be a lot of confusion over what Model-View-Presenter is. Martin Fowler currently calls the basic MVP pattern that I describe in part 23 ‘Supervising Controller’. He calls the amended version presented in this article ‘Passive View’ (as does this article).
I’m not quite sure why Mr Fowler calls the basic Model-View-Presenter pattern ‘Supervising Controller’ and not ‘Supervising Presenter’. It seems to me that the key difference between Model-View-Controller and Model-View-Presenter is that the Presenter in Model-View-Presenter can update the View directly. This is not permitted in Model-View-Controller; here the View updates itself from the Model. In the ‘Supervising Controller’ the Presenter/Controller can update the View directly.
Having said that I’m not sure that Mr Fowler would recognize the pattern described in part 22 as Model-View-Controller: this is closer to Model-View-Presenter as he describes it. As I mention in part 22 the pattern described is not ‘pure’ Model-View-Controller because the user events are initially sunk in the View (which is normal with modern UI widgets) and because there’s only one Controller and View per screen, rather than one per widget as in pure Model-View-Controller.
Finally note that I have adopted the ‘Passive View’ nomenclature in this article. However personally I think calling this pattern ‘Passive View’ adds to the confusion surrounding Model-View-Presenter. We already have the concept of active/passive Model-View-Controller and Model-View-Presenter as a whole, ‘active’ being the case where all Views get updated automatically on a change in the Model, ‘passive’ being where they have to update themselves. This is easily confused with an active/passive View distinction. Here an ‘active’ View is one that can update itself from the Model, whether automatically or not.
Conclusion
We have now covered quite a lot of the theory behind both Model-View-Controller and Model-View-Presenter.
Part 25 of this series of articles will show how we can use Model-View-Presenter in the CAB/SCSF using an SCSF Guidance Automation Pattern.
References
The two flavours of Model-View-Presenter described by Martin Fowler
http://www.martinfowler.com/eaaDev/PassiveScreen.html (‘Passive View’ in fact)
http://www.martinfowler.com/eaaDev/SupervisingPresenter.html (‘Supervising Controller’ in fact)
Martin Fowler overview of GUI Architectures, including Model-View-Controller and Model-View-Presenter
http://www.martinfowler.com/eaaDev/uiArchs.html
Good explanation of Model-View-Presenter, Passive View and Supervising Controller on CodePlex
http://www.codeplex.com/websf/Wiki/View.aspx?title=ModelViewPresenterPatternDescription&referringTitle=MVPDocumentation
MSDN Article with code example (although the article is a little confusing)
http://msdn.microsoft.com/msdnmag/issues/06/08/DesignPatterns/
See also the page in the Smart Client Software Factory documentation on Model-View-Presenter
http://www.codeplex.com/smartclient/Release/ProjectReleases.aspx?ReleaseId=5027