Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 944
Jonathan Avatar asked Jan 02 '10 09:01

Jonathan


2 Answers

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.

like image 114
Mark Seemann Avatar answered Nov 05 '22 01:11

Mark Seemann


It converts everything to string because everything in web is a string.

Basically - view model is supposed to be in 'ready to output' state. If web were made from numbers only - we would transform everything to ints/decimals.

Whole point of viewModel - to format data representable. In your case - size enum to small/medium/large. It's not that detaching logic from views makes this valuable - it's ability to adept your data for web in one way, one place.


Answering to comment =>

Yeah, that sits well. I'm doing the same. But thing to mention - I'm not against putting that into views too. Because views and view models are last in 'dependency chain'. I'm quite pragmatic and completely against only to situations when developer uses domain model as view model and requirements for view model gets in conflict with domain model (i.e. when developer adds new "domain objects" for representational purposes only).

like image 37
Arnis Lapsa Avatar answered Nov 04 '22 23:11

Arnis Lapsa