I was doing a code review today and seen that someone having a view model classes that besides of data contains different me开发者_C百科thods, like
GetTable, GetPdf, LoadSomeData etc.
I personally didn't like it, since prefer to have a "plain" view Model classes, containing only the properties and put logic either into Controller either additional Service.
But on review I was not possible to find good arguments for that.
What do you think, is it a good way (style) of having a logic in view Model classes? What are pros/cons?
EDIT: It was ASP.net MVC2 application. EDIT: Example (just from head) of such code..
public ActionResult SomeAction()
{
var model = new ViewModel();
model.LoadSomethingFromSomething();
model.AnotherMethod();
return View(model);
}
The principal of separation of concerns and the single responsibility principal dictates that the only "logic" that should be contained in the view should be that which manipulates how the view displays the data. Everything else should be in the controller. Semantically the view does one thing - displays data, anything unrelated to displaying said data - i.e. manipulating data, formatting data, loading data, converting data etc. should be handled by the controller.
In the real world, we don't always have the luxury of idealism, but in the ideal world, that's the way it should be. The principal of least surprise says that code should be in the least surprising place to find it. If I (as a code maintainer) need to fix something, I need to be able to find it quickly - if it's not where logic dictates I would find it, it provides unnecessary hindrance to my completing my tasks quickly and efficiently.
If GetTable pertains to loading a table construct (i.e. an HTML table) for the view, then perhaps it is relevant, if we're talking about getting table data from a database, then it is not.
I used to subscribe to the idea of totally "dumb" models.. I.E ones that don't do ANYTHING. However after using that idea in practice I found it wasn't ideal. I now subscribe to the idea that viewModels should know about how to create themselves from other objects.
I.E.
public ActionResult SomeAction(int? id)
{
var serviceModel = _myService.Get(id ?? 0);
var model = new ViewModel(serviceModel);
return View(model);
}
Basically, rather than adding methods to your model, create several constructors that take in objects used in that view model's creation. This frees up your controllers & service from knowing anything about how the viewModel works (meaning there is no object mapping code cludging up everything).
Then, to get an object out of the viewModel, you can do the following:
[HttpPost]
public ActionResult SomeAction(ViewModel model)
{
_myService.Update(model.MapToServiceModel() );
return SomeAction(model.id);
}
Your question feels vague to me. When you say view model, do you mean a view specific model constructed from your domain's model that a view consumes? In that case, I agree the view model should be pretty simple overall. The view shouldn't have to "think" much (ideally, it shouldn't "think" at all). Calling methods from a view (that aren't defined in helpers), even branching in a view, is a code smell to me.
IMO, controllers should also be thin and light. I like the real bulk of my logic to be in my models and also in the data access layer. Just depending on what type of logic we are talking about.
精彩评论