The Big UI Problem
Since the User Interface came on the scene of software development, it is constantly one of the biggest problems. It is really hard to design the architecture of the User Interfaces, User Interactions and deal with all the logic around, all the different states and behaviors. It is not an easy task also to separate the UI logic from the other layers of the architecture. On the other hand, even if you develop the whole application, you should start to think about how to automatically test the UI (unit tests, components tests, integration tests…), how to maintain it in a way that will reduce the regression, will easily let you add new functionality and the very important one – the new team members should be able easily get the idea or say it – readability.
The No-No Approach
- Get some data from the Database
- Create some visual controls to show this Data
- Add some visual logic
- Add some domain specific (business) logic
- Add some database logic
- Tighten up everything with some more event handlers
- Put all this in the ‘code-behind’
- Now you just messed up the things.
- And enjoy this portion of Spaghetti
The “Benefits” of this approach
- Can Not test it.
- Can Not maintain it.
- Can Not read it. (even if you write it)
- It is Not the faster approach.
- And much more…
I don’t think this “approach” needs more to say about, so will leave it like this.
UI Design Patterns - MVVM Predecessors
Let me start with the father, but still the so good and famous -
Model – View – Controller. It introduces 3 separate layers of abstraction. Where the Model stands for the business (domain) object model that in most cases is similar to the Database model. The View is the layer that will be shown to the end user. It is often passive, so leave the actual screen (visual) logic to be done by the Controller – the mediator between the View and Model. This is the most famous UI Pattern across the web – used extensively in ASP.NET MVC, Ruby On Rails and much more.
Model – View – Presenter – Derivative of MVC, with some changes. The Controller is replaced with a Presenter abstraction, which stands for a guy that will hold an instance of a View and a Model and will do the visual logic by calling methods of the View. Most of the time the View is abstracted with an Interface, so leave the implementation of the Presenter fully separate and as a result the View can be easily replaced with new one.
Presentation Model - by the father of the Enterprise design patterns Martin Fawler. Here the Presentaion model is holding the state of the UI and the data. The difference with the MVP is that the View is active, it gets the state out of the Presentation Model and is synchronizing it on every change. The Presentation model doesn’t know anything about the View.
Some years later this idea was modified slightly and fitted into the world of WPF with the name of:
Model – View – ViewModel
It was 2005, when this beautiful name was firstly mentioned by Josh Gossman in his blog post “Introduction to Model/View/ViewModel pattern for building WPF apps”. He described entirely the nature of the new UI pattern for building better WPF application. But four years later Josh Smith’s article (WPF Apps With The Model-View-ViewModel Design Pattern) in the msdn magazine really popularize the pattern and gave much more information about some of the not very well documented tricks. And that was the moment when MVVM became really popular and perfectly suited for building all types of WPF and Silverlight applications. Both WPF and Silverlight were evolving with MVVM in their blood, that’s why it so natural and well suited in their both worlds.
As every other UI pattern – it is mostly about ‘Showing and Reading Data’. The Model is the part that is concerned about the actual raw Data. It is those plain old CLR objects (POCOs) that represents each domain specific object and nothing more. Please note that these classes don’t have any business logic in them. This logic is separated in Services or Utilities alike objects. Example for Model classes are the well known Customers, Orders and so on.
This is the part that usually gets really messed and we should pay special attention to it. In the world of MVVM:
- It defines how the Data will be presented to the end user. The view usually uses the full power of WPF/Silverlight with the concepts of DataTemplates and Styles to define how will be presented each piece of data.
- Only plain XAML and nothing more. (Code-behindless).
- It is Stateless. The state that is important to the application is kept by the ViewModels.
- It is kind of Passive – doesn’t have any specific logic in it – business or UI related. It’s activity is mainly due to the fact that it synchronizes it’s state with the ViewModels. More about these later.
The ViewModel – “Model of a View”
This is the guy that separates The View from The Model. (Presentation Separation)
- Expose the model’s data via Properties. Each piece of data should be exposed out of the ViewModel via Properties, so the View can get it from the ViewModel and visualize it on the screen. Very often is doing some presentation logic, formatting and making the model data more User friendly.
- Keeps the state of the View in Properties. Examples are IsSelected, IsExpanded and so on. These properties are always synchronized with the actual visual objects that are exposing this Selection and Expanding functionality.
- Expose functionality to the View via Commands. Commanding is the very important part of MVVM, because this is the way a Visual object can bind and execute method that exists in the ViewModel. At the end using Commands, a Button can execute Command (functionality) from the ViewModel when the user initiate an action (like Clicking it). The actual benefit of this is much easier Testability (in contrast with the eventing and event handling patterns)
Now lets see how these 3 layers are communicating between each other.
- Data Binding – is the built-in way of Synchronization between The View and The ViewModel. When two properties are bound and the one changes – the other gets changed as well. This technique is so powerful and natural to me that I can not even imagine writing software without it. Please read more about Data Binding at msdn.
- INotifyPropertyChanged – Once you implement this interface and raise appropriately its only PropertyChanged event each bound property will be notified about the change.
- INotifyCollectionChanged – The same idea, but notifies Item’s controls for adding, removing or clearing operations over the bound ViewModel collection. There is built-in implementation in WPF/Silverlight called ObservableCollection.
- Data Templates – One of those things that really differentiate Silverlight/WPF from the other platforms. It brings the concept of Data Driven Development to a new level, allowing us to define how we want to represent each piece of data using the declarative and so powerful XAML. So the Template is a declaration of the look of an object (Model, or the better – ViewModel). Read more.
- Commands – As we discussed, this is the way to expose functionality out of the ViewModel, so the View can bind to it and execute it when it has to, based on the user actions. In the world of MVVM, the implementation of the Commanding pattern uses the so called DelegateCommand (RelayCommand). I really encourage you to read the full article about commanding.
- Messaging – It’s optional concept that uses shared media to decouple ViewModels, but still make it possible to communicate between each-other. So the very basic scenario is one ViewModel sends message to the queue and a second ViewModel listens for that kind of messages and does an action. You may implement it in a very different ways, according to your needs. But keep in mind that most of the MVVM toolkits have it ready for use. (And one of the best out there is the MVVM Light Toolkit).
- Decouple the ViewModels via shared media (Message queue)
- Send messages to the Queue
- Receive (Listen for) messages from the Queue
The Bag of Tricks
- Behaviors – gives us a way to define declaratively in XAML interactivity and also extends existing controls with new functionality. Behaviours can be attached to a Visual and this way add it new functionality like dragging, moving, floating, reflection and much more. They can be very helpful in order to separate any visual logic out of the View into separate behavior class, that do only something very specific.
- Value Converters – it’s a very useful technique to Convert a bound value to new one. Can be used for presentation purposes and converting a piece of data to something more readable. (Note that most of this can be done in the ViewModel directly).
- Template and Style Selectors – provides a way to apply data templates based on custom logic. Most of the time, you may use template selector when you want to use more than one data template for the same type data.
Benefits of MVVM
- Separation of Concerns.
- Can Test the UI.
- Can Read the code.
- Can Maintain the application.
- Can Reuse the view logic.
- Better Designer and tools support. (Blendability).
- And much more…
Thank you for your time!
I’ll keep this post codeless, but I’ve prepared for you an example project, that demonstrates every one of these techniques, in a very obvious way. It is called RadWebBrowser and is very basic(for the sake of simplicity) Silverlight out-of-browser Web Browser application. It also uses some of the great RadControls for Silverlight. I'm also using the Great MVVM Light toolkit - if you don't know it, please go there, download it and start using it.
Please drop me a line if you have any comments, questions or suggestion.
Download it here.