I have seen some confusion around the naming of the major UI presentation patterns, often with code being described as one pattern when actually it uses a different one. This usually happens because the goals behind each pattern are similar and the descriptions are a little too theoretical. I want this page to serve as a practical description of each pattern and to provide some concrete examples of what differentiates the patterns in the wild.
The Three Major UI Patterns
The three UI patterns commonly used in WPF applications are Model-View-Controller, Model-View-Presenter and Model-View-ViewModel (MVC, MVP and MVVM respectively).
Model View Controller
MVC was the original pattern, but the description of the pattern and the reality of how it is used have evolved. Fowler's page on the subject describes a controller as co-ordinating the behavior of a view, as if there were one controller per view. From the original Smalltalk MVC paper:
Each view is associated with a unique controller and vice versa
By that definition, we should expect controllers to look like this, with each controller clearly associated with one and only one view:
public class EditCustomerController : Controller<EditCustomerView>
Anyone who has used a web based MVC framework, however, has seen a very different style of implementing MVC. The success of recent MVC frameworks like Ruby on Rails, ASP.NET MVC and Zend have changed the working definition of MVC to a controller that handles many views. Controllers in this style typically look like:
public class CustomerController : Controller
public ActionResult List();
public ActionResult Show(int customerId);
public ActionResult Edit(int customerId);
public ActionResult Save(Customer customer);
public ActionResult Delete(int customerId);
Where each of the actions return a different view.
I think there is an argument to be made that Zend, ASP.NET MVC and Rails aren't actually MVC, because Controllers deal with multiple views, when the original definition clearly said they should be unique. But that's only at design time - at runtime, when a request is received, the controller typically only creates one view per request, so perhaps it does meet the definition. It's a very blurry line that I'm not sure I want to get in the middle of.
Either way, MVC has come to mean a controller that handles many requests for different views, so that's the definition I use. Controllers tend to focus on navigation between views, rather than long-running interactions with a single view. Magellan has this focus.
Model View Presenter
MVP is described as a derivative of MVC. But when you see working examples of MVP, they tend to look just like the original definition of MVC, with a unique presenter per view. WebFormsMVP is an framework for this for ASP.NET. Caliburn is an MVP framework for WPF. I've also posted an example of building your own for WPF.
MVP has been further split into two approaches - Supervising Controller and Passive View. Supervising Controller is the version that almost everyone uses, and closely matches the original MVC definition. Passive View provides even more testability, and would be possible in WPF by exposing every Routed Event and the controls directly to the presenter, but I have never seen it implemented in WPF (and I don't think I would want to).
MVP in the form of Supervising Controller looks extraordinarily similar to MVC. The major difference is suggested in this snippet on Supervising Controller:
For input response the controller operates in the presenter style. The user gestures are handled initially by the screen widgets, however all they do in response is to hand these events off to the presenter, which handles all further logic.
This is the critical difference. In MVC, the controller gets the event first, before the view does. In MVP, the view gets the event first and gives it to the presenter.
On the web we can see how that works - user input happens in the form of HTTP requests, so controllers handle those and then render the view. But in WPF, controls always accept the user input first - the controller can never handle the input before the view.
Model View ViewModel
Fowler described this as the Presentation Model pattern, but WPF and Silverlight developers have come to know it as the MVVM pattern thanks to a John Gossman article. The Wikipedia article on MVVM has the history, but basically, MVVM is a specific example of Presentation Model in WPF and Silverlight applications. Personally, I use it because the first two patterns start with "MV" so the third may as well too.
MVVM is similar to MVP, but the ViewModel contains both state and behavior, while in MVP the state is generally kept in the model. The other major difference is that in MVP, where the Presenter references the View and can tell it what to do, in MVVM the ViewModel doesn't reference the View - instead, the ViewModel exposes properties and raises events that the View subscribes to.
Summary of Patterns
- Model View Controller: Controller is concerned with navigation, and handles requests for many views. Controller typically creates the view and forgets about it. Controller gets user input before view.
- Model View Presenter: Presenter is concerned with a single View. The presenter and view have a meaningful conversation. Model holds state, presenter contains behavior. View gets user input and passes to presenter.
- Model View ViewModel: Much like MVP, but ViewModel contains both state and behavior. The ViewModel shouldn't have a reference to the View.
Identifying the Patterns
When you build a framework or spot some code, here are some concrete things to look for to identify the pattern. I'll use the term co-ordinator to refer to the third object in each pattern (Controller, Presenter or ViewModel).
- If the co-ordinator has a reference to the view, you might be using MVP.
- If the view is bound to properties on the co-ordinator, or the co-ordinator is the
DataContextof the view, you might be using MVVM.
- If the co-ordinator deals with navigation between multiple views, you might be using MVC.
- If the view calls methods on the co-ordinator, you might be using MVVM.
- If the view has to pass user input events to the co-ordinator, you might be using MVP.
Smalltalk-style MVC is impossible in WPF
As described above, in MVC, the controller gets input first, before the view. In MVP, the UI gets the input, and forwards it to the presenter.
An example is MVC4WPF. Controllers in MVC4WPF are associated with a single view and typically look like:
public class CustomerController : WPFViewWindowControllerBase<ICustomerView>
This looks similar to the Smalltalk type of MVC. But when I click a button, the view forwards that event to the controller. Based on the Supervising Controller definition above, this is really MVP, not MVC. The only way to achieve this style of MVC in WPF would be to have the controller handle events before the view - impossible with WPF.
Hello, I'm Paul Stovell
I'm a Brisbane-based software developer, and founder of Octopus Deploy, a DevOps automation software company. This is my personal blog where I write about my journey with Octopus and software development.
I write new blog posts about once a month. Subscribe and I'll send you an email when I publish something new.Subscribe