The ViewModel pattern (more formally called the Model-View-ViewModel pattern, but that’s way too long winded and I’m lazy) is an increasingly popular pattern with WPF and Silverlight developers. This is largely due to its simplicity and flexibility and its inherent support in WPF and Silverlight. It helps to separate business, presentation and UI logic which in turn helps with a whole host of development and design issues.
Having a clean separation between your application’s user interface and underlying application logic means that you can unit test it independently of the user interface. Automated testing of application logic through the UI can be complex and time consuming to setup. In addition, it can be difficult to isolate errors in the user interface or application logic portions of your application when they are both tested at the same time.
Another key benefit of using the ViewModel pattern is that it allows application developers to focus on application logic while user interface designers can focus on the visual aspects of the application. This allows the look and feel of the application to be defined separately from the underlying application logic, making it easier to maintain, modify (say as a result of usability feedback) or to customize.
The ViewModel pattern also makes the application easier to understand and maintain. It also provides more opportunities for code re-use, allowing application logic to be re-used in different parts of the same application, or allowing the user interface to be tailored to specific user roles or locales, or allowing application logic to be shared between desktop and RIA versions of the same application. In all of these cases, the underlying application logic is the same though its visual representation may be quite different.
There are many posts and articles out there that describe the ViewModel pattern (my favorite ones are listed at the end of this post), and they all seem to differ slightly in how they define or describe the pattern. This is, of course, totally reasonable. Patterns are just a way to describe a potential solution to a design problem and specific scenarios will call for a pattern to be modified to best suit the situation. I find the (invariably heated) debates that the so-called 'design pattern experts' engage in as they argue about the finer details of a pattern to be, let’s just say, tedious and unhelpful. What matters is that the spirit and the underlying principles of the pattern are understood and applied - the details don't matter nearly as much.
The ViewModel pattern is just one of many patterns that fall into the 'Separated Presentation Pattern' bucket. Essentially, the ViewModel pattern is a variation of the Presentation Model pattern (actually, some would say that the ViewModel pattern it is in fact the same as the Presentation Model pattern). Whatever your point of view, I'm going to describe what I believe are the essential features of the pattern. In my next post I'll show you some code that I've been playing with recently that applies the ViewModel pattern to collection-based models.
So what are the essential features of the ViewModel pattern? I describe the ViewModel pattern like this:
In the ViewModel pattern, the UI and any UI logic are encapsulated in a View. The View observes a ViewModel which encapsulates presentation logic and state. The ViewModel in turn interacts with the Model and acts as an intermediary between it and the View.
All of the separated presentation patterns exist to help separate UI from application logic by placing the various flavors of application logic and the UI into distinct classes or components. The differences between the various patterns are largely due to two things: the roles and responsibilities assigned to these classes, and how these classes interact with each other. Let’s look at the ViewModel pattern in these two respects:
The roles and responsibilities of the classes in the ViewModel pattern can be characterized like this:
The next thing to consider is how they interact with each other. The key here is to understand the two-way interaction between the View and the ViewModel. I think the essential feature of the ViewModel pattern is that the View is an observer of the ViewModel, which means that the ViewModel doesn't have a direct reference to the View. The ViewModel acts like a state machine and the View's responsibility is to render the state in whatever way is appropriate, and to influence that state by interpreting user input gestures.
The View typically extracts state from the ViewModel through properties that the ViewModel provides and changes of state in the ViewModel are communicated through events and notifications that the View consumes. In the other direction, the View captures user input gestures and interacts with the ViewModel to change its state. This can happen in a number of ways. The View can simply set a value on a property provided by the ViewModel. More complex state changes can be achieved through action methods that are exposed by the ViewModel.
You may have noticed that in the description of the ViewModel pattern above I don't make any mention of any specific WPF or Silverlight frameworks features. This is intentional since a pattern should be technology agnostic. Most of the posts and articles that describe the ViewModel pattern focus on the specific features of WPF and Silverlight that directly support the ViewModel pattern. In fact, these features do such a great job of supporting the ViewModel pattern that it becomes difficult to separate them from the pattern itself.
Let’s look at some of these features and see how they support the ViewModel pattern...
Data Binding: WPF and Silverlight data binding make it easy to bind a View to a ViewModel. Data bindings can be defined declaratively in XAML and are very flexible – you can pretty much bind anything to anything. The View’s DataContext references the ViewModel so that the View’s data bindings resolve to its properties and events. Two way data binding takes care of retrieving state from the ViewModel for presentation in the View, and for updating state in the ViewModel as a result of the user’s interaction with the UI. Change notifications fired by the ViewModel allow the view to be automatically updated whenever the ViewModel’s state changes.
Commands: While data binding provides a great mechanism for supporting two-way interaction between the View and the ViewModel for state exposed as properties, the ViewModel will often provide methods that represent actions that the user can initiate through the UI – submit an order, approve an expense report, etc. Commands provide a good solution for this. They allow controls in the View to be easily associated with actions that the user can carry out without requiring any UI logic glue code, and they allow the visual representation of the action (i.e. the UI) to be cleanly separated from the actual implementation of the command (i.e. the handler). WPF has much more extensive support for commands than WPF, but the basic mechanism can be used to allow a View and a ViewModel to interact cleanly.
Data Templates: The Data Template feature of WPF and Silverlight allow you to define a View entirely declaratively. This is great for Views that require no UI logic (no code behind) and are ‘pure’ UI. Data templates contain controls and their associated bindings. When a template is applied, its DataContext is set to the object that it's templating (in our case, the ViewModel) and the bindings take over. Data Templates allow you to focus on the presentation logic in the ViewModel and leave the ‘skinning’ of your ViewModel to a UI designer who can use a tool such as Blend to built the template without having to write any code whatsoever. WPF supports implicit data templates so you can associate a data template with a ViewModel type and wherever the system sees a ViewModel of that type, the data template will automatically get applied. Silverlight doesn’t yet support implicit data templates, but you can manually specify the data template for individual controls. Finally, WPF Data Template Selectors allow the system to choose a data template based on custom logic, say to account for user roles or location.
CollectionViews: I think WPF’s CollectionViews are actually good examples of ViewModels. They specifically support models that are collection based and they encapsulate presentation logic and state to support filtering, sorting, grouping and selection. They are easily consumed by Views through data binding, are independent of the UI and support unit testing. Silverlight doesn’t yet have as much support in this area, but it does provide the ICollectionView interface so you can implement something equivalent (this is the subject of my next post so stay tuned!!).
There are many other features in WPF and Silverlight – such as Styles, Visual State Manager, Triggers*, etc – that indirectly support the ViewModel pattern but the ones described above are the big ones. All of these features work together to help the View interact cleanly with the ViewModel. By ‘cleanly’ I specifically mean that they reduce the amount of UI specific code that is required to glue everything together.
* As a side note, I am not a big fan of triggers. They are very useful in some situations for defining visual behavior, but they can also be (mis-)used to define presentation logic in the view which is bad. I find the Visual State Manager a much better mechanism for defining visual behavior…
To summarize, getting the right code in the right place is the key to leveraging the ViewModel pattern to build flexible, robust WPF and Silverlight applications. Deciding where a specific piece of code should go can sometimes be difficult, but it gets easier with practice and the features that WPF and Silverlight provides help simplify this process dramatically.
Here’s a short of list posts and articles on the web that I’ve found the most useful and interesting
For those of you who are keenly awaiting my next post on navigation in Silverlight, this post and my previous post on view-first and presenter-first composition are really parts 2a and 2b of that series. I’ll be building on the concepts that I’ve described in these posts and focusing specifically on how navigation and the ViewModel pattern interact. Sorry it’s taken so long, but hopefully it’ll be worth the wait :-)