Question

Benefits of MVVM over MVC

Finally getting to do some Silverlight development and I came across MVVM. I am familiar with MVC and the article I was reading said because of XAML, MVC would not work out. Not having too much experience in XAML clearly is the reason I did not get this point.

Can someone explain why MVC is not suited and why MVVM is better for Silverlight development?

Thanks JD

 45  29568  45
1 Jan 1970

Solution

 63

Its a very slim distinction, which I can explain best by comparing MVC in ASP.NET and MVVM in WPF.

In ASP.NET MVC the request comes in from the web server and is handled directly by the Controller. The Controller determines the appropriate View and populates it with Models. The Controller then releases these instances to the underlying system which renders a result to the client. You can see that the Controller is first and last to act.

In MVVM, the UI (the View), faces the user and takes user input directly. Within the View, Commands within the ViewModel (which is the DataContext of the View) are triggered by this activity. Control flows to the ViewModel which interprets what the View has sent it and prepares its Models. After control flows back to the View it updates itself according to changes in the Models. If a new View is required, the ViewModel communicates this with the NavigationService (or whatever method of navigation your application uses), which is the purview of the Window or Frame--UI components. You can see that the ViewModel isn't first and last to act; the View plays a much greater role than in MVC.

The architecture of WPF/Silverlight is the reason why things are done this way. The command, binding and navigation infrastructures can't be controlled/replaced by the Controller; they are tightly integrated with the UI. So the Controller must sit below the View and take a more passive role.

2009-10-20

Solution

 17

Decoupling Components

In MVC, you have a triangular relationship between the components. That is: The Controller owns the View and the Model. The View relies on the definition of the Model. The Model needs to fulfill the requirements of the View. Think of a Hub (controller) and spoke architecture (view and model)

In MVVM, think of that triangle flattening out with each component only knowing about one other in the chain. That is: View->ViewModel->Model

The Model is unaware of anything up the stack. The ViewModel is only aware of the Model The View is only aware of the View Model - it is unaware of the Model.

Why is this important?

This is the core of the original question.

The main purpose is further abstraction of your architecture. This will typically lead to a bit more code, but fewer points of contact between objects. Fewer points of contact are important because this leads to more agile code. The more coupling/contact Class A has with Class B, the more impact a change in Class A will have. Reducing the impact of change is one of the key benefits of good architecture.

To fully understand this, it's helpful to ponder about what the components really represent. What is a View, a Controller, a ViewModel, or a Model? Are they literal definitions, or more of an abstract concept?

In my experience, it has been more beneficial to consider the Model to be a cluster of classes/objects which deal with the construction and persistence of data. It's not just a plain-old-object with properties. It's a class which performs data fetches, data saves, a factory which constructs plain-old-objects. It's a facade layer which provides a clear API into the data. Should this facade layer be referenced directly from the View?

In my opinion, it should not. In MVC, that answer is also "no". The Controller fetches data from the Model. In that regard, MVC and MVVM achieve the same goal. Where the two architectures differ is how the data and the view are linked.

Like the Model, the View can be a collection of classes which in coordination with one another, render a presentation view. This could consist of a View Controller + View in the case of mobile platforms (View Controller on iOS, Activity on Android). In a lot of cases, you need a class to load a view document into memory and update view properties. There's a lot of work to do here. In MVC, the Controller quickly becomes a 'kitchen sink' class - a sort of dumping grounds for anything related to the current user context.

When you multiply this over dozens of potential views within your application, you end up with a lot of deep dependancies between your back-end Model code and your front-end View code. With large Controller classes, these dependencies aren't immediately apparent.

Flattening out your dependencies

MVVM flattens out the dependencies. This creates focus. What is focus? The ability to work on a single piece of functionality without the distraction of all other dependencies. Now you can start writing unit tests on code that was previously deemed untestable.

The View Model acts as a facade between the View and the Model. The View Model caters to the needs of the View - technically the View should own the View Model. If the View requires data from multiple sources, the View Model encapsulates the composition of separate data sources into a single, unified, de-normalized object. If the view needs to call back into the Model or other destinations, the View Model provides hooks and routes the appropriate call.

Consider how a networking patch-panel works. At first glance, this seems redundant - why not simply wire your ethernet from point A to point B. But with experience, you'll understand that a patch panel provides you with a key piece of abstraction which allows you to alter the routes of Point B without affecting Point A. This is what your View Model is doing.

Now that you have a clean abstraction between your View and Model, the consequence should be that your View/Controller is only concerned with presentation. This means it shouldn't be dealing with localization or formatting - it gets data and presents data. Your View Model is an ideal place to put these sort of pre-view data massaging. Let's say you need to filter data based on a criteria. Again, the View Model is knowledgable about the Model data (your View is not) and is a great place to put this sort of code.

Once you start organizing your application requirements in this fashion, your View/Controller code becomes cleaner, and when something needs to change, the implications are more obvious, which leads to fewer bugs.

Testability

One final note on testability: By flattening out dependencies, it makes it easier to inject mock dependencies into your tests. It makes testing easier and more concise. Your View Model becomes something that you can define clear test cases against.

2014-12-17