Wednesday, February 18, 2009

Tom’s Patterns Cheat Sheet, Part 3 – Model View Presenter

Considered a descendant of Model View Controller, MVP comes in two main forms, which patterns god Martin Fowler calls Supervising Controller and Passive View. A significant variant of Passive View is the Humble View, which is epitomized by Michael Feathers' classic article The Humble Dialog Box, and a very significant variation of that is Presenter First.

Most discussions of MVP begin with MVC and proceed in chronological order, but I find this ordering illogical. From a practical standpoint, the primary reason to choose MVP is to increase testability of your UIs, so the logical starting point is the Humble View form of Passive View.

Passive View MVP

Passive View MVP

Dotted lines represent communication by events while solid lines are direct object messages. The roles of the components are as follows.

View: In this architecture the view is kept as "humble" (that is, as free of code and logic) as possible. UI technology is often difficult to unit test (though as Fowler says, this point is often over-stated) so the goal of Humble View is to remove anything from the view that might be worth testing. The view will generally not be covered by unit tests at all in this architecture.

Presenter: The view simply passes notification of user stimulus to the presenter, whose role is similar to a controller in MVC. The presenter accesses the view only through a UI-agnostic interface so that it can be easily mocked in unit tests. The presenter updates the model appropriately and can receive events from the model when its state changes. The presenter is entirely responsible for updating the view; the view has no direct knowledge of or interaction with the model. The reason for this is to simplify the logic and make the code more readable and maintainable by putting all UI manipulation code in a single place.

A presenter differs from a controller primarily in its granularity: presenters are created at the form/page/complex widget level, and not at the widget/window level as are controllers. Also in Passive View MVP presenters are responsible for updating the view as well as for responding to user interaction, while controllers are only responsible for the latter.

Model: As with MVC, the model has no knowledge of the presenter or the view.

Some other variations on Passive View:

Passive View MVP with a Presenter-Model Observer

By removing the View's direct knowledge of the presenter you can decouple the view from the presenter and allow the same view to be used with different presenters. There is however a penalty to be paid in loss of readability whenever the Observer pattern is used, and this can sometimes be significant.

Passive View MVP with a Model Interface

By adding an interface for the model you can improve testability of the presenter yet again. This can be used with or without the Presenter-View Observer. In fact I would encourage use of a model interface for all but the most trivial of models. At this point we've arrived at the MVP variant used by Presenter First, though Presenter First is really a variation of TDD, and so is as much a design/development process as an architecture.

It should be noted that Fowler considers the View interface optional, but from a practical standpoint we can assume its existence.

Supervising Controller

Historically, Supervising Controller was developed before Passive View, but logically it's the pattern you revert to in order to take advantage of data binding:

Supervising Controller MVP

With this pattern you would allow data binding of the model to the view to handle the "easy" synchronization work, and would reserve the presenter for handling any complex logic. Although this is structurally more complex than Passive View, in practice where data binding is strong it can result in far simpler code. The Presenter-Model Observer has been removed from the diagram above, but there's no reason it couldn't be added back if that were appropriate for the situation.

For additional variations on MVP, I found this to be an interesting post. I will reserve creation of MVP code samples for a future post.



No comments:

Post a Comment

Followers