As promised in MVP design pattern - Part 2, today post would cover something which generated a lot (very well deserved) noise last days - Microsoft MVC.NET framework. After some playing with the MVC.NET framework CTP bits and after reading some MVC.NET blog posts, I found myself thinking about next questions:
- "What is the difference between MVP and MVC? "
- "Having MVC .NET in place, do we need MVP?"
- "What is easier to use for TDD?"
This blog post would try to give answers on those questions
The role of view
If we would compare the diagrams of MVP and MVC patterns
we could see that MVP design pattern implementation has a view totally unaware of model. Presenter is the one exclusively communicating with the model and sending DTO (in case of Supervising controller) to model or performing direct manipulation with the view UI elements.
On the other hand, in MVC we have next two "read data" cases:
- a view reading data directly from model and perform "declarative data binding" of its controls or
- controller retrieving data from model, pass that context data to view while loading the appropriate view and view then binds to that sent context data
In most of the "update data" use cases we have a view sending updated context data to controller, where controller performs some validation and/or business logic and updates the model with that data.
In general, MVP pattern is based on standard ASP NET page controller pattern implementation, where Page A performs Response.Redirect("PageB") and that results with page B loading with complete page life cycle events fired etc. MVP adds to that sequence just one additional step: injecting the view to presenter (where view for presenter is just an UI technology abstracted view interface)
Beside that "default" ASP NET page controller based implementation, there are various ways how the MVP implementation can be enhanced.
One of them is the utilization of application controller and Page Flow Application Block (which I presented last week on my Web Client Software Factory session) where application controller centralizes flow and navigation concerns and behaves as shared context container for multiple views covering the same use case.
Page flow application block is a block using the NET 3.0 workflow engine enhanced with additional UI designer used in defining navigation flows. The end result is that you have a separate project with workflow definition describing navigation flow use cases. In a way, that is something very similar to the purpose front controller has.
Having in mind type of enhancement application controller and navigation flow AB bring to standard ASP NET, I am calling the WCSF sometimes "ASP NET web forms on steroids"
MVP summarized: Navigation is handled on a per page basis using page controller pattern approach.
MVC.NET framework is different - more "web suitable" approach to the same concern of efficient handling navigation. It is based on front controller design pattern driven routing engine, which in general represents intercepting of every http request on a http handler level and checking if there are mapped controller types responsible for handling intercepted Url.
As we can see on first diagram, the flow in MVC starts with controller class and not with web page - view (which is use case in MVP). When controller is been invocated, it usually:
- retrieves some data from model,
- performs business logic and
- picking the appropriate view to which he pass the processed model data
- loads the view - which then renders without the need of complete page life cycle being executed
In a way, that is something similar to what we have in Supervising controller MVP pattern, with a difference that in supervising controller the view (page) is still been loaded first and then the presenter class is been created)
MVC summarized: The navigation is handled in one centralized configurable place for all the pages based on front controller pattern.
I found one thing important enough to be emphasized here: Front controller (routing engine) is a part of Microsoft MVC.NET framework, but that is its separate part and pattern different then MVC pattern.
To illustrate how routing engine is important for MVC framework, I'll just mentioned briefly that I've been working on a POC which was supposed to handle on efficient way the need for having various page UI flavors of the same page - based on multiple business conditions.
I choose to built POC platform based on MVP pattern where multiple views (representing versions of the page) are sharing the same presenter (to remove redundancy) enhanced with custom (Maverick .NET based) routing front controller engine. The end result of this solution based on a front controller + MVP is something which looks (to me at least) very much like what I've seen in MVC.NET framework but just with standard web forms used.
Advantages of the MVP
One advantage I am particular excited about MVP is something David Hayden blogged about and Ron Jacobs talked about with Atomic Object guys. It is the fact that in MVP all you need to develop the presenter is an interface of the view. That interface of the view in passive view version of MVP represents page UI elements, so in a sense it can be considered as page abstraction or even as page contract between the UX (designers) and DEV (developers).
Although passive view is very cumbersome to be implemented and sometimes lead to complex presenters, the advantages of its usage are much higher in standard waterfall development process, because it enables tech leads to translate the FRD (Functional Requirement Document) requirements right at the beginning of development phase and produce sets of view interfaces (abstracted pages).
Therefore, communication on relation tech lead->developer is concentrated to the beginning of development phase with very precise set of artifacts defining requirements. Once the interface of the views would be defined and verified as the one matching the FRD requirements, developers are able to start developing their presenters including the unit tests to verify that FRD functional requirements are fulfilled well.
The end result of that activity would be a list of unit tests representing FRD requirements. Percentage of successfully "green" test of that list can be used then to track realistic project progress. 5 green tests of 100 FRD tests=> 5% progress report.
What we get as the end result is:
- totally decoupled and effective working streams of tech lead, developer and designer
- set of artifacts useful in tracking the real project implementation progress and as a guidance to developers what requirements they have to met.
IMHO, Second advantage MVP has is that while MVC pattern feels more natural in some web development scenarios, MVP pattern based development offers "crossing the boundaries" out of the box by utilizing the fact that presenter is not aware of the view UI used technology. Both view interface and presenter are living even in separate class library project which allows their re-usage in win form applications too.
I know, most of us thinks about that as "cool but YAGNI", "we are doing only web development", but once you would see how easy it is to get the smart client application from already built web application, you would start thinking about that too.
Think about another idea: win form UI development is much faster to be implemented and modified so imagine doing prototypes of your web sites in win form just to speed up process of verifying if business needs would be met with application. Once that would be verified, you would still use the same presenter you used for win form and build a web form UI layer on top of it but this time with already confirmed business expectations.
MVP and MVC in Test Driven Development
As stated already in this post, MVP biggest advantage is enabling writing presenter tests with only view interface available.
On the other hand, MVC.NET approach to TDD offer much more power with providing ability of mocking the flow itself (you can mock context, request, response) + providing the controller based testing on a way similar to testing the supervising controller (setting the context DTO to desired values to trigger certain test flows).
Although that looks maybe to someone on first sight as an overkill, according to the Jeremy D. Miler (and he knows what he's talking ) the simple nature of MVC route -> controller -> view makes writing complex web form tests much easier
I spent decent amount of time of this 2007 doing MVP tests in web forms and although there were a lot of hurdles during that time I face, I can not say that I felt too much pain mainly because I was mostly using either front controller or application controller as MVP supplemental patterns
Right now, to me too MVC looks a little bit more complex to be TDD-ed and I don't know if the advantages of the MVP can be achieved easily in MVC too, but I realize that I don't have too much experience with real world TDD-ing MVC usage but I know that I can relay on Jeremy's opinion.
The promise of having easier TDD experience with MVC in upcoming period is making me very happy and really eager to dive deeper in MVC, so be prepared for some blog posts on that subject (if anything left to be blogged after all this MVC .NET posts appearing last days like mushrooms after the rain