The Inquisitive Coder recently made a post about MVVM being overrated. He states a preference for MVP (a great pattern, and a great implementation of it for WPF is Caliburn). Whilst patterns are there to be
abused used as the needs of a project dictate. I think the arguments are subject to a common flaw in peoples thinking, especially around front-end patterns.
The primary attack on MVVM is that it violates the Single Responsibility Pattern (SRP). In short SRP states that a class should have one and only one reason to change. David suggests that ViewModels have 2 reasons to change (paraphrased)
- If, the Model changes
- If, the View requirements change ( i.e. needs more model data displayed/edited)
This is not what I take issue with, it’s true. But it’s true of all bridge classes and interfaces; DTO’s, Data Layers and UI’s. A bridge depends on both sides, but that is it’s responsibility. Sometimes the SRP is looked at from a much to granular view point and it leads to anaemic domains. People want to separate data from behaviour it seems to be human nature. I regularly hear SRP as the reason why this is good.
From Daniels post the 2 responsibilities a ViewModel has are:
- communication/interaction with the Model
- making data (from the Model) available so it can be displayed
The SOLID principles (of which the S stands for SRP) are a great way to evaluate code and patterns, but they take a back seat to the tenets of OO Design
- inheritance (I think this should be renamed Inheritance and Composition or removed as being implicit in polymorphism)
Encapsulation states thou shall not whore out your data to other classes. Whilst UI is a grey area for encapsulation as we all need to display our data. MVVM takes a step closer to encapsulation by keeping the behaviour and data together.
In my opinion ViewModels contain their data and the behaviour that relies on it in one place with the single responsibility of Modelling a View. If your ViewModels are two big or unwieldy then look at decomposing them into self contained Commands (with both data and behaviour) and/or smaller ViewModels with clearer responsibilities (an upcoming post).
After 18 months of MVVM I too am starting to wonder if the extra work required to maintain two-way synchronization (View-Model) is worth it for most scenarios. But that’s another topic and to do with choosing the right tool for the job. I still believe MVVM is the most elegant pattern for solving the problem it solves.