Monday, February 6, 2012

The Model-View-ViewModel Pattern

How the MVVM pattern became convenient
WPF has a very powerful databinding feature, that provides an easy one-way or two-way synchronization of properties. You can directly bind two WPF elements together, but the common use of databinding is to bind some kind of data to the view. This is done by using the DataContext property. Since the DataContext property is marked as inherited, it can be set on the root element of a view and it's value is inherited to all subjacent elements of the view.
One big limitation of using the DataContext property as data source is, that there is only one of it. But in a real life project you usually have more than one data object per view. So what can we do? The most obvious approach is to aggreate all data objects into one single object that exposes the aggregated data as properties and that can be bound to theDataContext. This object is called the view model.

Separation of logic and presentation

The MVVM pattern is so far only a convenient way to bind data to the view. But what about user actions, how are they handeld? The classic approach, known from WinForms is to register an event handler, that is implemented in the code-behind file of the view. Doing this has some disadvantages:
  • Having event handlers in the code-behind is bad for testing, since you cannot mock away the view.
  • Changing the design of the view often also requires changes in the code, since every element has it's different event handlers.
  • The logic is tightly bound to the view. It's not possible to reuse the logic in an other view
So the idea is to move the whole presentation logic to the view model by using another feature of WPF, namely Commands. Commands can be bound like data and are supported by many elements as buttons, togglebuttons, menuitems, checkboxes and inputbindings. The goal here is not to have any line of logic in the code-behind of a view. This brings you the following advantages
  • The view-model can easily be tested by using standard unit-tests (instead of UI-testing)
  • The view can be redesigned without changing the viewmodel, because the interface stays the same.
  • The view-model can even be reused, in sone special cases (this is usually not recommended)

What's the difference between MVVM, MVP and MVC?

There is always some confusion about the differences between model-view-presenter, model-view-controller an MVVM pattern. So I try to define and distinguish them a bit more clearly.

MVC - Model-View-Controller

The MVC pattern consists of one controller that directly gets all user input. Depending of the kind of input, he shows up a different view or modifies the data in the model. The model and the view are created by the controller. The view only knows about the model, but the model does not know about any other objects. The pattern was often used in good old MFC and now in ASP.NET MVC

MVP - Model-View-Presenter

In the MVP pattern, the view gets the user input and forwards it to the presenter. The presenter than modifies the view or the model depending on the type of user action. The view and the presenter are tightly coupled. There is a bidirectional one-to-one relation between them. The model does not know about the presenter. The view itself is passive, thats why it's called presenter pattern, since the presenter pushes the data into the view. This pattern is often seen in WinForms and early WPF applications.

MVVM - Model-View-ViewModel

The model-view-viewmodel is a typically WPF pattern. It consists of a view, that gets all the user input and forwards it to the viewmodel, typically by using commands. The view actively pulls the data from the viewmodel by using databinding. The model does not know about the view model.



1 comment: