Robert Martin says: "There should never be more than one reason for a class to change".
Let's consider the ViewModel class which is bound to a View. It is possible (or even probable) that the ViewModel consists of properties that are not really related to each other. For small views the ViewModel may be quite coherent, but while the application gets more complex the ViewModel will expose data that will be subject to change for different and unrelated reasons.
Should we worry about the SRP principle in the case of ViewModel class or not?
views:
443answers:
4Yes, but that doesn't mean poor design couldn't force you into it.
The ViewModel single responsibility is to provide the View the information it needs. If the View needs different and unrelated properties is not important as the ViewModel only has one reason to change and that is the View showing different properties. So you shouldn't worry too much.
That said, if the ViewModel does gets huge, maybe you could about think dividing the view into several subviews to improve reusability and keep the Views and the ViewModels manageable.
I agree with gcores.
Once you see ViewModel grow to more than two screenfuls of text, it is time to consider splitting ViewModel into several child models.
Another rule of thumb is that I never have more than two levels of nesting inside XAML file -- if one part of the view becomes too complex, it is time for view refactoring -- extract inner XAML into separate UserControl and create corresponding ViewModel, which will be default data context on child view.
I agree that splitting your screens into multiple Views with multiple ViewModels is necessary to reduce bloat and complexity. Here's another pattern I've employed to help stick to SRP using MVVM:
Here's one scenario. My ViewModel needs to obtain data and respond to filter commands from the UI. I create the ViewModel to be composite in structure. That is, child classes that have access to private members of the ViewModel perform linear tasks such as handling the filtering. I might also have another child class that performs the necessary logic for selection of items based on criteria. You get the idea. Once the ViewModel is performing certain functions that span across several methods, it may be a good candidate to delegate to a child class. The child classes remain part of the main ViewModel, so it's just a way of reducing the size of the ViewModel and makes unit testing these linear operations easier.