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.



No comments:

Post a Comment

Followers