views:

111

answers:

4

(I am using ASP.Net MVC, but this seems like a more generic MVC question)

Say you have a domain model representing a person, and you have a view for editing a person. Included in the Person domain object is a State of Residence property, and in the view you want a dropdown that lists states.

Is there any reason not to create a view model that derives from the domain model and simply includes properties for the UI spiciness the view requires? If so, why would not not want to do this?

TIA

+5  A: 

I would think that deriving a view model from a domain model would introduce coupling that MVC was intended to avoid; however, that said, do what makes the most sense for your application.

I prefer to have view models separate because doing so leaves me free to dramatically change the domain model and get improved compile time support for remapping my view model to the new domain model.

kbrimington
" domain model would introduce coupling that MVC was intended to avoid" This statement isn't true at all. Django/RoR implementations in which the viewmodels are actually tightly coupled representations of the database schema. MVC doesn't make an opinion about what your model should be, only that it is not part of your V and C.
jfar
From Wikipedia: Many applications use a persistent storage mechanism such as a database to store data. MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the model. Models are not data access objects; however, in very simple apps that have little domain logic there is no real distinction to be made. Active Record is an accepted design pattern which merges domain logic and data access code - a model which knows how to persist itself.
jfar
@jfar: Your point is well taken; however, plenty of MVC's own examples use Linq-to-SQL or Linq-to-Entities or DataSets *as* the domain model. All of these models have at least some coupling to the persistent storage mechanism, and are used as models (often enough) in practice.
kbrimington
@jfar: I am pretty new to MVC, but that is what I thought. I have also seen it argued that a viewmodel should only be used when necessary, but if not, using the domain model is fine. However, I have never seen it discussed whether deriving a viewmodel from a domain model is a good or bad idea, which seems quite strange - if it is acceptable practive to bind a view to a domain model, why not to a a viewmodel derived from a domain model?
erg39
@jfar: The question here isn't whether a model should reflect the data store, but whether a *ViewModel* should inherit from the model. In my applications, they do not for the reasons I describe, though I take a more pragmatic, rather than dogmatic, approach to it. I don't disagree with models coupling to the data structure. I just believe that View Models should couple *more tightly* to the view than the model.
kbrimington
@kbrimington: you are correct WRT many MVC examples. Wouldn't it be better practice though to have that Linq-to- stashed in a repository than part of the domain model directly?
erg39
@erg39: I agree. It is best to be pragmatic about when to use and not use view models. When I use view models, they tend to reflect the view, its settings, and complex relationships rather than simple CRUD to a single table. Inheritance of the model rarely serves well in these circumstances.
kbrimington
@erg39: I think it depends. The repository pattern is growing in popularity, but it's still new and there are other viable approaches, including binding right against a Linq-to-SQL model. I find the repository pattern useful if I'm scaling up an API for distribution and use by other parties, but a bit cumbersome for my internal applications.
kbrimington
@kbrimington: But don't you ever have situations that are basically "CRUD with benefits", a CRUD view that requires more data than the domain model (such as the dropdown in the question's scenario) but do not have complex relationships and the like? What do you do in such a scenario?
erg39
@erg39: (Speaking with caution because what I do is not necessarily divine truth...) In these scenarios, I create a POCO for use as a view model. I don't inherit from the model, because I'm only interested in the data *structure*, not the *behavior*. For a drop down list, I might have properties for the selected value and text, and a collection/array property for the lookup value set. In summary, if I'm using a view model, it is organized deliberately to make data binding super easy, and I worry about mapping the model to the view model elsewhere.
kbrimington
@kbrimington ": The question here isn't whether a model should reflect the data store" I'm just responding to the answer. The answer is based around an incorrect statement.
jfar
@erg39 "a CRUD view that requires more data than the domain model (such as the dropdown in the question's scenario) but do not have complex relationships and the like? What do you do in such a scenario?" Actually this is very easy to solve. I use a technique right now where I substitute relationships with html form elements. a 1:many maps pretty well to a dropdown and works great with automapper. Think orthogonally about this problem.
jfar
@jfar: Fair enough. I've always understood the MVC pattern to be a pattern to increase testability by decreasing coupling between data structure/access, application logic, and presentation. I'm willing to let our understandings differ.
kbrimington
+2  A: 

No, you don't really want to do this.

A big part of the reason to use ViewModels is because your domain entities tend to be big, spiky, complex and tied to persistence mechanisims. All leading for them to have strange, interesting or destructive behaviors when they encounter things such as the DefaultModelBinder.

By using much simpler ViewModel classes, you can avoid the bulk of these problems while also further decoupling your UI layer from your domain model.

Now, what you should do is provide easy means to generate a ViewModel from a Domain Entity or to updated a Domain Entity from a ViewModel.

Wyatt Barnett
+1 for the comment about the tendency of domain entities to be bound to persistence mechanisms. I find that with POCOs for a view model that I am less likely to encounter bizarre serialization behavior.
kbrimington
Could you expand on the comment "what you should do is provide easy means to generate a ViewModel from a Domain Entity or to updated a Domain Entity from a ViewModel." Do you mean generically? Writing a bunch of per-viewmodel entity update code is something I would like to avoid unless necessary.
erg39
You can do a number of things to ease the job--such as AutoMapper--but depending on how far your entities and your viewmodels diverge, you could have some manual code to maintain.
Wyatt Barnett
+6  A: 

This is not a recommended practice and since you are asking you should not do it. The short answer is create a unique view model for each and every view you are going to render. Maintain a 1-1 view to viewmodel relationship and as you code you will see why.

The long answer can be found here amoung other places http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx

Thank you,

R

Fire Garden
I understand the use of viewmodels, but even the link you cite concludes "If you are able to bind directly to domain model in simple cases, that is the simplest and easiest solution." Scenarios such as the cited in the original post is barely more than what is contained in the domain model (though I am not arguing it might not fall apart if it grows in complexity). I understand that many (most?) feel deriving a viewmodel from the CRUD domain model is not ideal. I just do not understand, if using the domain is simplest and easiest, why this is the case. Thanks.
erg39
A: 

I disagree with most of the advice here.

I think that your domain model should be clean and a viewmodel does what it has to. If your view needs a person and the time in London i dont see the problem with doing this:

ExampleViewModel : Person {
 Public DateTime LondonTime { get; set;}
}

Or

AnotherViewModel 
{
 Public Person SomeGuy { get; set;}
 Public List<Kitty> Cats{ get; set;}
}

If your view needs a person and a list of kitties

This keeps your domain clean; the time of London is not related to a person however on your view you still need get the data. This is the whole point of a view model imho.

aaron
First example should favor composition over inheritance
mathieu