Tuesday, March 17, 2009

A First Look at Model-View-ViewModel

Model-View-ViewModel (MVVM) is a pattern used extensively by WPF developers. It was first introduced in October 2005 on WPF-and-Silverlight architect John Grossman's blog, where it was billed as a variation of MVC. According to Grossman, Expression Blend was written entirely using the MVVM pattern, and it is now, as far as I can tell, far and away the most common pattern used by WPF programmers.

I'm new to WPF and to MVVM, so I'm not going to claim to be able to make any definitive pronouncements about it. Most of what I've learned about it has come from reading this MSDN article, which was written by Infragistics engineer Josh Smith, and which Grossman himself recommends, as well as from reading various blog posts and newsgroup threads. But I will attempt to give some initial impressions, which I will hopefully refine and correct over time.


What is MVVM?

First of all, even though Grossman and others refer to it as a variant of MVC, it appears to me that MVVM is exactly Presentation Model, which is why my last post was a recap of Presentation Model. So far as I can tell, there is no structural or conceptual difference between MVVM and Presentation Model that could be used to classify it as a separate pattern. It is simply the application of the simpler form of Presentation Model to WPF applications. Smith agrees with this, saying "I consider MVVM to be a specialization of the more general PM pattern, tailor-made for the WPF and Silverlight platforms."


MVVM as an Adaptation of Presentation Model

You may recall that the simpler form of Presentation Model that I discussed in my last post was this one:



Presentation Model pattern in which the View references the Presentation Model

This is the simpler form because the view references the presentation model, and not vice versa, so the presentation model can be written without any entanglement with the view whatsoever. Also I mentioned in my last post that where data binding is present this pattern is especially simple, which is the case in MVVM. So here is the pattern as applied to WPF applications (from here on out I'll switch to the MVVM terminology and call the presentation model a "view model"):



MVVM Pattern

WPF Elements in MVVM

The diagram above is clear, but not very interesting. Here is a diagram that shows where the WPF pieces fall into the MVVM pattern (click on the image to see a larger version):


WPF Elements in the MVVM Pattern

I'll be the first to admit that I may be focusing myopically on the sample program that Smith provides with his article. I'll update this as I learn more, but meanwhile, based on that example and on a smattering of reading, this is what I see:

View: Consists of all of the XAML in the application, including the XAML for the main Application, for the Windows and for any UserControls, plus any Styles and DataTemplates. WPF data binding is used to bind controls to view model classes, and DataTemplates map view models to WPF controls for presentation.

Once the developer puts the basic view in place, they would ship it off to a UI designer in accordance with Microsoft's strategy of separating those two roles, so the view model needs to be well separated from the view.

View Model: Application, Window and UserControl XAML code-behind falls into the View Model layer, but it is strongly recommended that code-behind code be minimized, and that View Model code be placed in separate classes to the extent possible. Those classes are the view model classes shown above.

View model classes are data-bound to the view, so they need to implement INotifyPropertyChanged in order to notify the view when it needs to be updated.

They may optionally expose Command properties, which are classes that implement the ICommand interface. WPF provides built-in support for a command pattern that allows you to easily associate a single handler with a menu item, toolbar button, context menu, short cut key, etc. E.g. you can associate a single "Copy" command handler with the "Copy" menu item, toolbar button, context menu and "Ctrl-C" shortcut key. Commands therefore provide a way to encapsulate some of the behavior of the WPF application in the view model classes.

Granularity of view models appears to be roughly one per Application, Window and UserControl, but that isn't set in stone.

Domain Model: Happily, our domain model never changes as we move from pattern to pattern. That's one of the best things about these patterns. Our efforts to create controllers that can be reused from one UI technology to another only rarely prove fruitful (what are we supposed to do with all those Windows Forms MVP presenters now that we're told we should use data binding in WPF applications?) But the domain models just keep chugging right along, oblivious to the world's UI churn. They are the only (mostly) completely reusable parts of the system we have.

Anyway that's it for my first look at MVVM. I will (hopefully) try to update this as I continue to learn about WPF.



Monday, March 16, 2009

Tom’s Patterns Cheat Sheet, Part 5 – Presentation Model

Overview

Presentation Model (also called Application Model) is a pattern that is similar to the MVC family of patterns in that it consists of a domain model, a view and a "something else" that acts as a mediator between the model and the view.

That "something else" is the
presentation model. A presentation model differs from the controller in MVC and the presenter in MVP primarily in the way it is conceived. A presentation model is conceptually an object model that represents the view. E.g. if your view contains two textboxes and a checkbox, you would expect to see two string properties and a boolean property in the presentation model:



Simple Presentation Model Example

In this example, the logic associated with enabling or disabling the "Offline enabled" checkbox is handled by the presentation model, as is the code that interacts with the domain model, which is in this case the authentication service.

Controllers and presenters, in contrast, are conceptually handler classes that act as conduits between the domain model and the view. A presentation model is stateful, because it is considered the "system of record" for view state, while presenters and controllers are likely to be stateless. In fact Fowler comments that "the basic MVC notion assumes that all the state of the view can be derived from the state of the model," so in classic MVC there is no view state.

Controllers, using Martin Fowler's
description of MVC, tends to be very granular - one ore more controllers for every widget. Presenters tend to be more large-grained - typically one per form. Presentation models tend to be larger-grained as well, similar to presenters, although composition of presentation models is also common, particularly in the Model-View-ViewModel (MVVM) variant used by WPF developers.


Components of Presentation Model

The presentation model
: An abstraction for a view's state and behaviors. Like the presenter in MVP, the presentation model is intended to be free of UI dependencies, and for the same reason: One of the primary motivations for Presentation Model is to improve the testability of the system by moving as much logic as possible out of the view, where it is difficult to test.

The view: As in MVP, the view in the Presentation Model pattern is intended to be as free of logic as possible, again to improve testability.

The domain model:
The domain model is conceptually the same in Presentation Model as in MVP.


Variations of Presentation Model

Fowler identifies two variations of Presentation Model, one in which the view references the presentation model, and one in which the presentation model references the view:



Presentation Model pattern in which the View references the Presentation Model




Presentation Model pattern in which the Presentation Model references the View


Fowler provides a code sample of the first variant here. This variant is simpler than the second one, especially in cases where data binding can be used or where the Presentation Model->View observer can be dispensed with, because the presentation model has no dependencies on the view at all, or even on a view interface.

But if data binding is not available and if you want to test the code that synchronizes the presentation model's state with the view, then the presentation model will need a reference to the view, so the second option is required.
Another important variation is MVVM, which is used extensively by the WPF community. I will attempt to comment on that pattern in the next post.


Pros and Cons of Presentation Model

As with MVP, one of the main motivations for using Presentation Model is to improve the testability of the system.

As with any Separated Presentation pattern, following the pattern may make it easier to support multiple views or to change UI technologies, although in practice this benefit is often overstated.

As with MVC and MVP, Presenter Model allows you to separate the UI technology from the UI logic, which makes the code easier to understand and to maintain. Compared to MVP, Presentation Model can lead to a cleaner, simpler presenter / presentation model object model, because by encapsulating view state as well as behavior the presentation model disentangles itself entirely from the view.


Presentation Model may lend itself better than MVP to situations in which you want to create an automation object model for your user interface that would be usable by SDK programmers, because the presentation model object model is closer to what a programmer would expect to see in an automation object model. Although some developers have exposed the MVP presenter for use in this way, they generally are not as user-friendly as presentation models.


On the downside, because it maintains its own view state, Presentation Model introduces the need to synchronize the view and the presentation model, although this can be mitigated by data binding. It makes use of the Observer pattern, which decreases readability and maintainability of the system. And it increases the number of moving parts in the system, which can decrease maintainability in small applications.

Followers