Last time, we saw the Please Wait screen which turns asynchronous calls into synchronous application behavior. This time, we'll take a look at the MVVM pattern and how it relates to our sample application.
The Model-View-ViewModel (MVVM) Pattern
As you've probably noticed, the XAML Tips application does not use the Model-View-ViewModel (MVVM) pattern. We won't go in depth on the pattern (we'll save that for another day). We'll just take a look at some basics, the the reasons for using the pattern, and why we did not use the pattern here.
First the basics: MVVM is a design pattern that is concerned with the presentation layer of the application. As noted by the name, it consists of 3 parts. The Model consists of the business layer of the application (and everything below that). We can think of this as everything except for the presentation. The View consists of the UI elements (the XAML) that the users sees and interacts with. The ViewModel is the goo that holds the Model and View together. It takes advantage of the flexible databinding model that is available in the XAML world. Basically, the XAML elements are databound to properties and objects in the ViewModel (the View never directly interacts with the Model). The ViewModel handles the communication with the Model to populate these objects and to make method calls through to the Model.
Now that we have seen the parts of the MVVM pattern, let's take a look at why we would want to use the pattern. The benefits of the pattern are to resolve 3 main problem spaces:
- Problem Space: Mixture of Presentation and Business Logic
MVVM encourages good separation between the presentation and business layers of the application.
- Problem Space: Unit Testing of the Presentation Layer is Difficult
MVVM makes it easier to unit test the presentation layer by separating the UI elements (the View) from the presentation functionality (the ViewModel).
- Problem Space: File Sharing between Designers and Developers
MVVM makes it easier to manage source code because the designers can be working with the XAML files (the View) while the developers work with the code files (the ViewModel and Model).
- Cost: Added Complexity
MVVM adds complexity to the presentation layer that requires an additional learning curve by the development team.
- Cost: Errors Move from Compile Time to Run Time
MVVM works through the flexible databinding mechanism in Silverlight/XAML. Incorrect databinding does not cause compile-time errors, so a number of errors are moved to run time.
Why No MVVM in XAML Tips?
There are a couple of reasons why the MVVM pattern was not used in the XAML Tips application (or more correctly, in the application that XAML Tips is based on).
First, the application would not take advantage of the benefits of the pattern. Let's take a look at each of the benefits:
- Mixture of Presentation and Business Logic
As mentioned in the Introduction, we had been using CSLA as a business layer framework in other applications. Because of this, we already had the separation of concerns between the UI and business layer. As such, we already had a resolution for this problem space. Note: CSLA is MVVM compatible (it really deals with the "M" part of the pattern), and there are helper objects to make working with the pattern easier.
- Unit Testing of the Presentation Layer is Difficult
At the time the application was written, we were not making extensive use of unit testing. The testing that we did have was focused on the business layer. In addition, the UI for this application was fairly simple (primarily CRUD operations). As such, we were not doing unit testing of the presentation layer.
- File Sharing between Designers and Developers
For this application, the designer and developer were the same person (me). As such, we would not get the benefit of the separation of the XAML and code files.
Second, as noted in the Introduction, this application was a first Silverlight production application. We were trying to limit the number of new/unknown parts to the development. Since we did not fully understand the environment we were working in, it would be difficult to correctly implement the MVVM pattern. We would most likely have had several design issues and/or kludges to get things to work as expected. Now that we have the basics under our belt, we are better equipped to understand what a good implementation of MVVM would look like.
MVVM is a Good Pattern
It's hard to do any work in the XAML world without running across the MVVM pattern. It is a good pattern, and I recommend its use. But as with all patterns, there are benefits and costs. We should make sure that the benefits outweigh the costs in our implementation.
If I were to re-write this application, I would most likely use MVVM. We could take advantage of the pattern to abstract some items (such as our Please Wait functionality) and to use databinding more extensively.
The Good, the Bad, and the Ugly
We've taken a look at a lot of different parts of our XAML Tips UI implementation. Some things we like, some things need some changes, and some things need complete re-writes. Here's where we ended up:
The application behaves like a WinForms application (which is not necessarily bad). But we can be more creative with our presentation based on the flexibility that XAML offers us.
Look and Feel
Having the style and brush resources centralized in the App.xaml is good. This allows us to change the overall look of the application by making just a few changes. The gradient design looks dated; we should look at updating the colors and styles to match current design sensibilities.
The ICloseQueryable interface may be better served with a base class that exposes a Closing event. Alternately, we could add an auto-save functionality that would make this unnecessary.
The form manager needs some better error handling in managing which form is docked in the client area (adding and removing the children from the UI element). Also, we can look at a filmstrip-type interface that would change the way that the user interacts with multiple forms.
The popup message is a good implementation. We can make this a little more visually interesting by changing the animation to behave more like "toast".
Please Wait Screen
There are too many problems with the Please Wait screen to use it as-is. The risk is that the entire application will be locked up if the screen is not hidden appropriately.
While the application did not use the MVVM pattern for the reasons stated above, we should reconsider this (based on being comfortable with the environment and understanding the pattern). The ViewModel could be used to enhance the operation of the form controller, the popup message, and (most importantly), the Please Wait functionality.
There were quite a few decisions made when this application was originally created. Some of those decisions have stood up to the test of time, and some of those decisions have not. The important part is that we take the time to go back to applications that we've created and take a look at them with a critical eye. By reviewing what we did, we can pick out the parts that are good, the parts that need some improvement, and the parts that really need to be thrown out.
Our creations are never perfect. And that's okay. As long as we can admit that things can be done better, we can learn from our experience and move on. If we ever think that an application is perfect (and refuse to budge from that view), then we've just slipped into the mode of being stuck in our ways.
Application development is about continuous learning ("development", if you will). Let's keep learning and keep moving forward.