As I work with the MVP / Passive View / Humble View pattern more in ASP.NET, I’m gaining an understanding of some common smells or anti-patterns that can happen when you try to implement this pattern and haven’t quite grokked it yet. Some of these are problems I’ve had to pull out of my own code:
TOO MANY PRESENTERS SPOIL THE BROTH
When you re-use a user-control or even just a view interface on different pages, it’s tempting to re-use a special little presenter inside each of those pages whose sole responsibility is for presenting that usercontrol. If you have two different flavours of page, you might even put the call to the presenter into a BasePage.
This is fine as long as those pages need no other pesenter logic, but there are usually other controls on the page too, and they’ll need to be presented, and before you know it you have two or three or a whole crowd of presenters yelling at different bits of your page, telling them what to do.
Lesson: This is the path of darkness and complexity on the tightrope of your untestable UI layer. Re-use presenter logic by all means, but do it inside the presenter layer, where you can test. Everybody say Ahh… Tests…
Maxim: No more than one presenter to be constructed per page / request.
THE SELF-AWARE VIEW
Within a request / response cycle, only the Page should be aware of the existence of a presenter. The HUMBLE VIEW (implemented in a UserControl) does what it’s told without any knowledge of who is dishing out the instructions. Find this smell by looking for UserControls which construct their own private little presenters, or worse still accept them as properties (usually so that they can do filthy things like call methods on them – see ARROGANT VIEW, below).
The arrogant view is not only SELF-AWARE, but has the temerity to imagine that it has the right to give the presenter direct instructions. Thus a presenter can easily be relegated to nothing more that a PROXY MODEL, with logic creeping up into the untestable view layer. Find this smell by looking for presenters which offer public methods. Replace these direct method calls from view->presenter with a more humble OBSERVER PATTERN, where the view raises events containing the relevant information in the EventArgs, and the presenter reacts accordingly (or decides not to, as is its privilege).
PRESENTER BECOMES PROXY MODEL
When you have an ARROGANT VIEW that commits the crime of directly calling methods on a presenter, you start to see the logic in the presenter thin down to the point where it becomes little more than a proxy for the ‘model’ (in classic MVC terminology) or service layer. The whole idea of MVP is to delegate the responsibility of figuring out what to fetch from the service layer and when to fetch it, so that the view just gets on with displaying whatever the presenter decides it should display. When an ARROGANT VIEW gets these kind of notions, logic that belongs in a (testable) presenter is tangled up with display logic in the view, and it’s time to roll up your sleeves and refactor.
Hows things going at BBCWW, maybe you remember me? 🙂
Wow you jumped on that pretty quick! How did you find me so fast?
Things are going great thanks, I certainly do remember you – you’re still a bit of a legend around the corridors of Woodlands you know!
Hey Matt, I was tag-surfing ASP.NET and came across your post. Legend eh! 🙂
What is bad about the THE SELF-AWARE VIEW? Whether I wire up a presenter in the control, or in the page, I typically use the same pesenter class. Are you saying to use the same presenter instance among different controls on the page?
We found that we quickly reached over-complexity by having UserControls responsible for creating their own presenters. Often those little presenters would go back to the service layer for the same data as another one somewhere else on the same page, resulting in unneccesary calls to the database. We found it was less painfull to have one main presenter (created by the base class of the page) which was then responsible for creating all the ‘widget’ presenters and passing them the data they needed to get their work done, including a reference to the UserControl as exposed by the main view (page).
That’s just my experience, your milage may vary of course 🙂
Thanks for a Great post. So check out http://blog.elliottohara.com/2009/02/presenterfactory-and-mvp-base.html
I played around a bit and was able to get rid of “only the Page should be aware of the existence of a presenter”.
Tell me what you think!
Leave a comment