Search code examples
asp.net-mvcseparation-of-concernsmvvm

ViewModels and rendering


In several sample projects, I've seen ViewModels being used to convert data objects into strings, for use in the View.

The ViewModel will typically have a constructor that receives one parameter - a data object. The constructor will then populate various properties of the ViewModel (mostly strings and ints).

This prevents any complex logic from occurring in the View.

At first glance, this seems like a good idea to me, as it more fully enforces separation of the View from complex logic.

For example, say my view was trying to render a property 'Size' of a data object, Size being a number between 1 and 3 representing 'Small/Medium/Large'.

Instead of having a if/switch statement in my view, I would just have a 'SizeString' or something similar in my ViewModel, and the if/switch statement would go in the ViewModel constructor.

Does anyone disagree with this approach?

Would it be better to use some other approach, such as helpers? And if so, why?


Solution

  • The purpose of the ViewModel is to represent (a part of) the complex Domain Model decomposed as primitives that can be rendered in some form other other.

    This decomposition must take place somewhere. It may involve some simple kind of logic, such as my favorite example: converting a discrete value (OK, warning, error) into colors (Green, Yellow, Red). This is the essence of what a ViewModel does, so my default approach would be to encapsulate this logic into the ViewModel itself.

    Consider the alternative: If not implemented in the ViewModel, then where? If you put the logic somewhere else, you end up with a ViewModel that's basically just a structure without logic. Letting a ViewModel encapsulate the transformation/decomposition of a Domain Object fits well with the Single Responsibility Principle.

    Although this is my default approach, I'm always aware that the logic may need to be reused across multiple ViewModels. In such cases, this may be an indication that the original ViewModel is really a complex ViewModel made up of several sub-views. In such cases, you can extract the common logic into a sub-ViewModel that encapsulates only that little part.