Disclaimer: What follows are the author’s opinions. If you are easily disturbed by alternate viewpoints, you are advised not to proceed with the reading of this document. You may continue to read only at your own risk. The author is not responsible for any side-effects (such as flaring of the nostrils, redness to the face and ears, increased heart rate, etc.) that may be manifested as a result of reading the contents of this article. This article may contain statements that may be disturbing to some readers.
Introduction
If you have done even the slightest amount of WPF or Silverlight development you will undoubtedly have come across the term MVVM. And if you have done any search on the term you will have come across a tremendous amount of ‘discussions’. These ‘discussions’ tend to be pretty ‘opinionated’ and heated (thus the disclaimer). You would also find a lot of different interpretations of the definition as well as it’s relation to the plethora of other pattern definitions. None of this really helps with what you were originally seeking. What you were searching for was more in line with: what is this thing, how do I use it, and why should I use it? It’s now more than five years since the term was first used and there is still a lot of ambiguity. Why is that? A pattern, by definition, is intended as a communication mechanism to help us convey understanding. It provides the mechanism to communicate a concept, an approach, to solving a problem.
Sometimes we get confused not because the technology or the subject matter is so complicated but because of the way things are portrayed or presented, even named. The way we learn is through association and if the association is not a good one then we’ll wind up more confused than enlightened.
What if it doesn't look like a duck?
If you call something a duck it should look like a duck, walk like a duck, and quack like a duck. Otherwise…don't call it a duck. Likewise, if you call something a pattern then there are certain expectations on the part of the reader (implementer) for it to be interpreted as a pattern. To start with, I’d like to offer up a definition of design patterns:
“Although many of the problems frequently encountered in software designs have existing solutions, solutions can be difficult to adopt due to the need to understand their details. Design patterns address this problem by being general; a solution documented in the format of a design pattern can be understood without knowledge of the specific details involved. Moreover, the standardized naming of design patterns makes communication among developers easier.” (Source:http://www.wordiq.com/definition/Software_design_pattern).
So patterns are a categorization of existing solutions. You find patterns in existing solutions. Why?, to be able to communicate that information. How?, by generalizing the concepts in the solutions. To what end?, so that others will be more readily able to implement those patterns in different environments.
To demonstrate the point, consider the Observer Pattern described here. As you can see, not only is the pattern clearly described in generic terms so that the concept can be readily understood, but you can see how it can be easily implemented in different environments. Is there any doubt as to what the observer pattern is or how it could be implemented?!
In the beginning…
John Grosman defined MVVM here as: ”Model/View/ViewModel is a variation of Model/View/Controller (MVC) that is tailored for modern UI development platforms where the View is the responsibility of a designer rather than a classic developer.” …”Model/View/ViewModel also relies on one more thing: a general mechanism for data binding. “
The above tells me that MVVM, being a variation of MVC, is an approach at implementing the separated presentation pattern. I interpret the first sentence to indicate that MVVM is defining an approach that allows for the UI (View) to be developed independently from the rest of the application. That’s good. It follows the goals of the separated presentation pattern and takes it one step further. This implies that there has to be loose coupling between the UI (View) and the rest of the application. And in the second sentence the author indicates that one way to implement that loose coupling is through data binding. That is also good. It not only allows for parallel development, it provides for independent testing of the application logic.
If the platform being targeted provides a data binding mechanism, then the pattern can be implemented. If we stopped here I think things would be (almost) fine as far defining MVVM as a pattern. The definition readily conveys the concept and also provides a generic mechanism for implementation. Unfortunately, the requirements of UIs go way beyond simple data binding and as a consequence MVVM relies on quite a lot more than ‘one more thing’.
Side Note: I’m not making any assumptions as to the class structure being used in the application. I don’t think it really matters for this discussion. If you have your data validation in the Model or ViewModel depends on your analysis and where you think it fits best. So I’ll use ‘application logic’ to mean some class in the application with which the View will interact.
Today’s applications include a wide range of controls required to design the rich User Interface users expect. Since the first line in the MVVM definition indicates that it’s addressing the UI, the complex interactions of these controls need to also be addressed by the pattern. As a result, for MVVM to be a pattern it needs to also define some generic ‘loose coupling mechanism’ for these user gestures (captured through the controls) to be communicated to the main application logic. An implementer of the pattern would then be able to take this generic approach and implement it with whatever facilities might be available in the targeted platform. I think you can quickly see that this “just ain’t gonna happen”. The variety and complexity of the controls and design requirements mitigate the possibility of a single generic mechanism.
A Rose by any other name…would be misleading
I’d like to take a short digression which might help in illustrating the point further. In this blog on MVVM, John Grosman writes: “My team has been using the pattern feverishly for a couple of years, and we still don't have a clean definition of the term ViewModel.”(Note, emphasis mine). And further in the same article; “One problem is (that) ViewModel actually combines several separate, orthogonal concepts: view state, value conversion, commands for performing operations on the model.” (Note: I suggest you read the whole article; it is very enlightening to see how the author struggles with the importance of naming, which is an important part in conveying the concept behind a pattern).
The struggle with naming is one definite clue that perhaps something is amiss. A pattern should have a clear and descriptive name. The problem then, is that MVVM is encompassing too many “separate, orthogonal concepts”. And I would go further in stating that the list indicated above is far from complete. There is quite a bit more UI functionality that needs to be addressed in a loosely coupled way.
Along the same lines, Martin Fowler writing about MVC here states : “It's often referred to as a pattern, but I don't find it terribly useful to think of it as a pattern because it contains quite a few different ideas.” MVVM, being a variation of MVC, would fall under the same critique.
Both references resolve to the same issue. A pattern needs to be clear as to its intent and provide a generic solution to a specific problem.
Let's not throw out the baby with the bath water
At this point I think we can clearly see that MVVM should not be portrayed as a pattern. It would require defining too many ‘orthogonal concepts’ as part of the solution, if even possible. MVVM does not, and cannot, provide an implementer with enough information to implement a solution. There are just too many aspects to the implied solution to be fully captured in a pattern.
So let’s see however, if we can capture the spirit of MVVM instead. We may then be able to provide some guidelines as to how to go about implementing the concept. At this point let’s not consider MVVM as a pattern and as a result we don’t presuppose there is an existing solution. Instead I think it might be more beneficial if we simply considered it more along the lines of a design goal. Looking at the original definition of MVVM, in my opinion, I see there’s a single requirement: independent development of the View from the application logic. Everything else, benefits and drawbacks, are a consequence resulting from implementation of the requirement. Now, you may say that implementing loose coupling in the design of the view results in being able to develop the View independently of the application logic. If so, then perhaps, we should first discuss the chicken and egg conundrum and then proceed with MVVM. That’s it. I don’t think anything can be said regarding the spirit of MVVM. Now let’s see what the consequences of that single goal might be and how it might be implementable.
The most immediate consequence of the requirement is that ALL interaction between the View and the application logic must be implemented through some form of loosely coupled mechanism. As we discussed above there isn’t a generic mechanism available for the user gestures (through controls) to be communicated, in a loosely coupled manner, back to the application logic. However what we do have is a collection of mechanisms to facilitate most of the situations. These include:
- Data Binding,
- Commanding,
- Triggers,
- Attached Behaviors,
- Custom (roll your own as needed)
Depending on the design of the UI and the actual controls required to implement it and the complexity of the user interaction, one or more of the above mechanisms will come into play. A simple read-only view may only require data binding. I’m guessing that the norm for any complex application is that you’ll need all of them. It’s important to note that these mechanisms are available to varying degrees in the targeted platforms and even varies between releases. That means that the custom part indicated above may be more extensive in Silverlight2 than in WPF.
That’s it, we defined a goal and we have the means to achieve that goal. Later we’ll discuss in more detail some of the other consequences (benefits and drawback) but first there are a couple of other UI issues that need to be addressed simply for completeness. After all we are primarily concerned with the design of the UI as a separate development effort and any implications this may have.
There are two conditions that occur in typical applications that are related to the UI and need to be addressed in the context of our design goal. First, the underlying data of a control being displayed in a View may change from other sources than directly from the View. Under these circumstances the application logic needs to communicate that condition to the View in order for the View to update itself and reflect the current data (or state). Because we do not want the application logic to have any knowledge regarding the specifics of the rendering of the data, this message needs to use a generic mechanism. Additionally, to comply with our goal it needs to be implemented using a loosely coupled mechanism.
The second condition is similar and occurs as a result of data validation. Under these conditions the application logic needs to communicate back to the View any error messages associated with user entries. As above this needs to use a generic mechanism in a loosely coupled manner. The solution is to use the standard facilities available through the INotifyPropertyChanged and IDataErrorInfo.
Separated but not isolated
So the premise with MVVM is that the View can be developed independently from the main application logic and that the main application logic can be tested without requiring the UI. However, at some point they both need to be combined in order to create one whole application. In other words the View and its supporting class need to be created within the context of the application and introduced to each other so they can communicate.
There are a number of different ways to accomplish this. The first and simplest is probably through the data templating mechanism described in this article by Josh Smith. Another is using dependency injection similar to that provided by the Unity container in Prism. A third way is through a Locator service similar to what’s provided with the MVVM Light Toolkit. Or you may have to create your own instantiation mechanism based on specific application requirements.
An informed consumer
It is extremely easy to use Visual Studio to create very complex application using the built-in design facilities of ‘click and shoot’. Defining event handlers and accessing the control through a direct reference is what we’ve been doing for years as the norm. We’ve been able to implement very complex functionality with very little effort. So let’s first, consider these questions:
- Can you create modular/maintainable code behind files?
- Can you develop applications with separate UI designers?
- Can you have automated testing of your applications?
I think the answer is “Yes, but…”. The ‘but’ meant that even though it was doable it was not without extensive effort and diligence. So let’s now consider the benefits of MVVM. We can see that it will:
- Naturally results in a more modular design
- Inherently facilitate parallel development (separate design groups)
- Results in a design that is much easier to test with a higher test coverage
All of these are ‘freebies’, beneficial consequence of our original goal. These are all very powerful benefits if you needed them and make use of them. If you don’t have separate UI designers or plan on automated testing then perhaps it’s not such a good deal, because, as with everything in life, there is a cost. As indicated above, designing through the Visual Studio built-in facilities is pretty intuitive process. However, even with the availability of several toolkits and frameworks it is (arguably) more difficult to develop MVVM applications. The main reason I think is that you still need to master the various loose coupling mechanisms. And these mechanisms are not fully supported through the design tools. MVVM applications may be (arguably) more complicated to maintain since more functionality has been embedded in XML which is (arguably) not the most intuitive language. AND the UI designer is no longer simply concerned with the visual aspects of the application and may need to acquire additional skills.
In summary
I hope that by removing the label of pattern and its associated expectation and by looking at it from another perspective this provided some clarity as to what MVVM is. As far as the how there is no way to completely cover the subject since it definitely depends on the specific design requirements so only an overview of the mechanisms involved could be described. And finally the why, a very subjective question. I would anticipate that this would be a question that gets answered as part of the architecture design analysis. As with everything else the benefits have to outweigh the cost. The size and complexity is probably the primary indicator. For large applications it’s most likely a slam-dunk. For the rest, you’ll be able to make an informed decision.