1. Introduction

Writing an application with good practices and a proven architecture design is comparatively easy if we are going to write a new application. But most of the time, we are working on existing applications, where change is not easy to make. If we ever get a chance to rewrite an existing application, then probably we won’t repeat the same mistakes which we or someone else did due to reasons such as time constraints, technology limitations, scope creep, etc. It would be better if we can somehow refactor existing codebases for betterment, with no or minimal risk.

MVVM is a proven Design Pattern used heavily in a lot of WPF / Silverlight applications. But it might be possible that we already have lots of code base that is not taking advantage of it. This article is for those who already have an application rather than starting a new one and wants to take an advantage of MVVM. In this article, we are going to see how we can take small steps towards MVVM. There are two major parts to this article. In the first part, we are going to study the evaluation of MVVM. In the second part, we are going to see the different steps to achieve MVVM. Although some steps have major rework and a potential of high risk, there are a few things which have no or minimal effect on the project.

2. Evaluation of MVVM

Let’s take a look at MVVM from a higher level and take a step by step approach to understand it. Our discussion is based on the complexity of the architecture from simple to complex, not from historical order.

Probably the simplest design principle to separate data from its presentation is the Observer design pattern [1]. In The Observer design pattern, we have two different classes for data (subject/model) or its presentation (observer/view). Subject classes contain the instance of all of the observers and send notification to all of the observers when there is any change in the data. Here is a simple block diagram of the Observer design pattern:

The next step is to introduce a middle layer in between the data and its presentation. The main purpose of this layer is to communicate between these two components. This is the main concept of Model View Controller (MVC) [2]. It is shown in this block diagram:

This approach has some advantages and disadvantages. The main disadvantage is that our view is not totally independent of our model. Model View Presenter (MVP) [3] handles exactly the same problem. In the MVP model, there is no relation between the View and the Model.

MVVM is very similar to the MVP pattern. Or it is some sort of specialized form of MVP pattern. In MVVM, the Presentator is known as the ViewModel. The Model communicates with the ViewModel with notification and the ViewModel communicates with the View with data binding and command binding, as shown by this block diagram:

Now let’s take a look at MVVM in a little bit more detail. What is the biggest advantage of this? It's first advantage is that our presentation is totally unaware of our model. We don’t write any user interface specific code in the ViewModel and all the communication is based on data binding and command binding. This means, we can easily write unit tests for it. We can easily change any user interface or even change the data model easily. Here is a detailed block diagram of MVVM:

This diagram explains how we can take advantage of MVVM. The most important thing in this pattern is to properly design the ViewModel. WPF has a very orthogonal design. This means we can customize or enhance the different parts of the library without affecting others. Most of WPF reusability is based on composition rather than inheritance. Therefore we can take its maximum advantage even at run time. Because, we can change the composition behavior at run time easily, but not inherited components. In this block diagram, we see the major components of the WPF class library which we develop, enhance, or customize in most WPF applications:

3. Switching to MVVM

We are going to start with a simple application, that is not written in WPF, and gradually make step by step changes in it to introduce the MVVM pattern. Our starting point is a loan amortization application written in VC++ and using WPF [4]. The reason to pick that application is, by definition, we can’t use MVVM with VC++, because XAML support is very limited in VC++ (the only support as of now is to load XAML at runtime and use it).

Although it is possible that we have some properties in our class that stores data, we usually have fields to store information. In our starting project, we have a class to store information about each payment. Here is our class:

Note that the user interface code is heavily coupled inside the business logic, in this case calculating the loan amortization. There is no simple way to write test cases to check this calculation without involving the user interface.

The XAML of our project is very simple. Here is the complete XAML code of our program:

Also note that like other programming styles, here we have a name for every control.

3.1. Step 1: Use Properties

If the code is using fields not properties, then convert those from fields to properties (this should have no or minimal effect on existing source code, because I choose the property name very similar (or same) as fields). We simply change to properties instead of fields in this step. Here is an updated version of our program:

There is no change to the XAML of the program. If we use the same property name as the previously used field, then we don’t have to change anything in the code. In our example, I use the Letter case for properties and Camel case for fields, so we update the source code accordingly and use Letter case there.

My first step is to change the data model to make it WPF friendly. To do this, I will either implement the INotifyPropertyChange interface or make them dependency properties. If we already have properties, then this should have no effect at all for the rest of the project. The rest of the code should be the same and should work the same, but at least now you have your model ready.

In this example, we are going to change our properties to dependency properties. In the following steps, we will see an example of the INotifyPropertyChanged interface too to see both variants. Here is our updated code:

3.3. Step 3: Use Data Binding

The next step is to use data binding. This will reduce a lot of codebase. Now it shouldn't have any code like:

txtName.Text = firstName;

This is a major change in the code base. But in this step, I focus only on the data not on the behavior. My code still has an event handler and should work fine, but now I don’t have to worry about updating the data into the control or getting data from the control to my variable. (No more control to variable interaction.) Now we only check the invalid input directly from the properties (they are automatically getting values from the user interface). Here is our validation code now:

Also note that now we no longer need to specify the name of the control; with the help of data binding, we will automatically get the values in the correct property (dependency property in this example).

3.4. Step 4: Refactor Event Handler

This is an intermediate step. I already have all the data handling in the form of data binding with no control/variable code in it. I am going to iterate through all the event handlers and whatever code is written there, move them into a method and call that method from the event handler. This is the updated version of our event handler now:

3.6. Step 6: Add the ICommand Properties

Now I am going to add properties in my class (which had the event handler earlier). The type of the property is ICommand. This again should not have any effect on the rest of the code. The number of properties should be at least the same as the method I called inside the event handler and I choose a similar name.

Also note that now all of our business logic is in the method, not in the event handler. This means now we can somehow perform unit testing on those methods without any user interface involvement.

3.9. Step 9: Define the ViewModel Class

Define a class to the ViewModel and move all the ICommand interface properties and methods assigned to it in this class. We introduce an event type property in our ViewModel class to handle the close event.

Note that this class doesn’t have any user interface element (other than a few message boxes in data validation, which can be removed easily if use the DataValidation in XAML), so we can easily write test cases on it. In addition to this, if we want to change the presentation of this, such as WPF to Silverlight or Console based application, we can do it very easily. This class contains all the business logic and now it is up to the user of this class how to present that information.

3.10. Step 10: Define the ViewModelBase Class

Let’s do one more step. We might want to do the same thing again and again, so why not create a base class to have a minimum ViewModel functionality to reuse it in other ViewModel classes. One more reason to create a ViewModelBase class is to show how to implement the INotifyPropertyChanged interface. Here is the code of our base class:

In this class, we raise the property change event whenever there is a change in the property. There are lots of other things we can do to improve our code base, but this is just a first step in the right direction. We can easily include more steps in the following guidelines, but after following these steps, we will have a reasonably good design of our program towards MVVM.