共用方式為


The ViewModel Pattern

ViewModelGear

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.

Variations On A Theme

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.

ViewModel In A Nutshell

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.

ViewModel 

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:

Roles & Responsibilities

The roles and responsibilities of the classes in the ViewModel pattern can be characterized like this:

  • The ViewModel encapsulates presentation logic and state. Presentation logic is defined here as the application logic that is concerned with the application’s use-cases (or user stories, user tasks, workflow, etc) and defines the logical behavior and structure of the application. The ViewModel is NOT a control’s code behind. Presentation logic should have no idea what its visual representation will be like and should be independent of any specific user interface implementation. To maximize re-use opportunities, the ViewModel should have no reference to any specific UI classes, elements, controls or behavior (like animations). It should not derive from any UI base class (ideally it should be a POCO). It should (of course!) be unit testable and be able to function without any UI at all.
  • The Model encapsulates business logic and data. Business logic is defined here as any application logic that is concerned with the retrieval and management of application data and for making sure that any business rules that ensure data consistency and validity are imposed. To maximize re-use opportunities, Models should not contain any use-case or user-story specific behavior or application logic.
  • The View encapsulates UI and UI logic. Views define the specific user interface for a piece of the application. Views are typically just controls that are designed to work well when bound to a ViewModel. Their specific role is to present the user with a user interface that represents the application’s underlying data and logic in the most appropriate way, and to interpret user input gestures and forward them to the ViewModel that then defines how they affect the underlying data and application state in the Model. In some cases the view may contain UI logic – application logic that is specific to the user interface implementation – in the view’s code-behind file. However, such UI specific code is difficult to test and should be avoided as much as possible. Of course, there will be times when the View will have specific behavior that cannot be expressed declaratively in XAML so there may be some code in the View's code-behind, but this code should be specifically focused on managing the UI controls in the View and should not implement presentation logic.

Interactions

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.

The ViewModel Pattern in WPF and Silverlight

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…

The Right Code in the Right Place

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.

More Stuff On ViewModel

Here’s a short of list posts and articles on the web that I’ve found the most useful and interesting

oO------Oo

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 :-)

Comments

  • Anonymous
    January 31, 2009
    PingBack from http://www.anith.com/?p=4252

  • Anonymous
    February 02, 2009
    Nice article, but the question remains for me. Are the variants MVVM and MVC really different? A Controller act between a view and a model. The View could directly access the model data. The ViewModel provide both in my option: Native Model Data and rehashed data for easier data binding. But at the end, the viewmodel encapsulate the state and controlls the program flow. In my opionion, the only reason for the slightly different ViewModel is the aspect of data binding.

  • Anonymous
    February 02, 2009
    Thank you for submitting this cool story - Trackback from DotNetShoutout

  • Anonymous
    February 02, 2009
    Thanks ChaosSpeeder, The ViewModel pattern is closer to the MVP pattern than to true MVC, though I’ve seen many descriptions of MVC that are actually MVP with the name ‘controller’ instead of ‘presenter’. I guess one man’s presenter is another man’s controller... Either way, you’re right – there isn’t that much different between MVP and ViewModel, except in as much as the View is strictly an observer in the ViewModel pattern. ViewModel and Presenter both act as an intermediary between the View and the Model and may or may not rehash the Model’s data for display in the View. In the Supervising Presenter pattern, on the other hand, the view has direct access to the Model (through data binding) and the presenter acts to coordinate the interaction between the View and the Model by sitting off to one side. This is a much more significant difference than any minor differences between ViewModel and MVP…

  • Anonymous
    February 11, 2009
    In this post, I'm going to describe an implementation of ICollectionView for Silverlight that allows

  • Anonymous
    February 18, 2009
    Hi, may I translate your interesting article to japanese and publicize on my blog? I’m looking for information about ViewModel pattern, but I found little infomation written in japanese. I want to introduce this useful pattern in japanese. Thanks alot.

  • Anonymous
    February 19, 2009
    Hi Shiroica - Absolutely. Please feel free to translate into Japanese. David.

  • Anonymous
    February 21, 2009
    Thank you for your lenient treatment. I publicized your articles "The ViewModel Pattern" and "CollectionViewModel". http://blog.sharplab.net/computer/cprograming/wpf/1842/ http://blog.sharplab.net/computer/cprograming/wpf/1840/ If these are not convenient for you, please let me know. Thank you!

  • Anonymous
    March 13, 2009
    There have been several great blogs and articles about the Model-View-ViewModel pattern lately. I thought

  • Anonymous
    April 28, 2009
    Welcome to the third post in my series on navigation in Silverlight! The goal of this series of posts

  • Anonymous
    June 09, 2009
    During the last few weeks I was working with Silverlight again quite a bit. This meant I had to write