Nick’s Blog

MVVM

by Nick on Nov.12, 2010, under Silverlight

I was recently watching a video presenting the concepts behind Microsoft’s newish programming model MVVM (Model, View, View Model). You can find the video within the article here. The reason for watching the video was that I really wanted to know what MVVM was and I really cannot complain about the content from that point of view. After watching the video I had a clearer understanding of what MVVM is.

The easiest way for me to explain MVVM is to ask you to think of a typical VB6, ASP.Net, WinForms, or Silverlight application. In all these cases there is a form or a view with control and then behind the scenes there is code that fills the controls are reacts to events. In all of these cases we are separating the view from the code and we often call this code “code behind”. However the code behind still has to have knowledge of the view and this means testing this code behind is usually left to visual inspection by a tester rather than being tested by any automated script such as a unit test. There are exceptions to this, there exist tools that can test that a GUI is doing what it is supposed to do but most people find these tool cumbersome to configure and the resulting tests costly to maintain.

So what does MVVM bring to the table? Well what Microsoft are trying to encourage is that the code behind has no knowledge of the user interface. The view model contains all the code that calculates what values should appear in what controls but stops short of actually putting the values in the view. Instead the view model will have a property and the view will be responsible for fetching the value as required. Conversely values entered into the view will be pushed to the view model as they are changed.

The reason that this is advertised as being a good thing is that we can then write unit tests that exercise the view model and test that it responds as expected. So, in other words, if you expect that inserting a value into field A will cause the text in field B to change it is now simple to write some code that writes a value to field A and tests field B.

Do you know how we would have tested this in the old days? We would have told some guy to run up the application and insert a value in field A and check the value in field B. Now I’ll admit that if you are unit testing the form against some mock data source then doing this in the running application might be more difficult. But what really crushes the MVVM idea for me is that the view is now effectively late bound to the view model. So any errors will only become apparent at run time or worse, there will be no errors it just will not work.

If you watch Jason’s video you will notice a few moments where he “forgets” to update the binding properties in the view and the application does not complain, it just does not work. So this means that however carefully you craft your code behind (or view model) and however carefully you craft your code behind unit tests to confirm that the behaviour is correct, you can mess it all up and get a run time only problem simply by binding the view incorrectly to the code behind. So, in other words, no matter how carefully you test your code behind, you are still going to have to test the view. After all that work separating the view from the code behind you are left with a system that still requires rigorous manual testing.

Routed commands! You know, I actually like the idea that you couple a user interface elements to something that knows if it is available or not. The result is that buttons or menus can be enabled or disabled automatically based on the condition of the command and all the user interface elements that invoke the command are consistently updated.

In Jason’s case he wanted the submit button to only be enabled when he had entered some text into the stock ticker. So he created his code so that the Enabled property (actually it was called something else) was available when the tickers text value was not empty. He fired up the code and sure enough in the initial state the button was disable. He started typing text and the button remained disabled. The reason was simple, binding only updates the underlying value when the field loses focus. OK so that is something you cannot infer from code inspection and I am a bit of a fan of the idea that you look at the code and can see what it does. His solution was to change the text fields binding properties so that after each change it submits the value to the bound view model. Now I call that coding. OK sure it does look like -

public void Ticker_OnChange(sender,e)
{
    CheckCommandCanSubmit();
}

And coding should not be in the user interface according to all the Guru’s. Besides, if you have any coding experience you will instantly see what my code is doing. I can include comments to tell you if you really like. But what seems to be going on is that they are saying that the view needs to have real knowledge of the view model. In other words, if I change my view models way of validation I might also have to update my view, and if I update the way I want my view to work then I will have to update my view model. So ultimately there is no separation of concerns, the view and the view model and simply one and the same. Great you can add some unit testing, but it is unit testing you will have to repeat over and over again during user testing and not some black box deep in the guts of the application that the user could never have hoped to have tested.

:, , ,

Comments are closed.

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!