One common question when applying DDD is how to interpret other architecture’s concepts of a “model”. For example, two common presentation architectures are MVC and MVP. In each of those acronyms, the “M” is short for “Model”. So what exactly is this Model? Is it the Domain Model? Presentation Model? Something else entirely?
This question came up recently on the DDD list, and naturally, a slew of wide ranging answers came pouring in. One of the problems with trying to marry these two concepts is that MVC is a rather old concept, with roots almost 30 years old now. The concept of a “domain model” certainly wasn’t invented by Eric Evans. However, it takes some sleuthing to understand if the DDD model concept applies to MVC. It’s rather clear that the original concept intended that the “M” is “domain model”. Randy Stafford pointed this out in one of the replies to the original question, also suggesting an alternative name to the separate Model concept, “Model Model View Controller”. Another is the concept of “Model View ViewModel”.
Personally, I don’t like either of these names. Rather than come up with a different name, the real question comes down to, “should I use my Domain Model as my Presentation Model?” Lately, I’ve leaned strongly towards NO.
Keeping our POCOs safe
When programming in an MVC architecture, you’re often playing by someone else’s rules. We strive to make our entities POCOs (Plain Ol’ CLR Objects), and completely persistent ignorant. Just as the persistence layer is an infrastructure detail, the View and Controller technology are a similar type of infrastructure, just at the other end of the pipeline. If we create our POCOs, then expect them to be used in the Controller and View (especially as things like arguments to a controller action), limitations on the technologies make our objects look like all sorts of crazy.
Now, no one really suggested making entities as arguments to controller actions, as the MVC technology can’t support the richness of our POCO objects. But what about the model passed to the View? Still, because of the limitations of MVC technology, the Model used in a View must look a very certain way for binding to work correctly. For example, in MonoRail and ASP.NET MVC, collections usually need to be arrays, and properties need to be read-write for binding to hook up properly. The same holds in MVP architectures, where the View technology is very sophisticated, but needs a Model that “plays nice” with its expectations. Otherwise, you won’t get any of the benefit of the underlying technology.
But we don’t want our entities to be sullied by these outside forces. We want to create rich models, untouched by persistence and presentation concerns. But to take full advantage of our presentation/view frameworks, we have to create something else. That “something else” goes by a couple names, both “ViewModel” and “Presentation Model”. I really like this concept, not only because of my zealotry for POCOs and DDD, but because it’s a natural manifestation of the Separation of Concerns principle.
Separating our presentation concerns
In addition to presentation/view frameworks requiring their models to look a very certain way, often many concepts belong only in the presentation layer. Things like required fields, type checking, and other invariants are a product of the task of interpreting user input. Since all data comes as text over the web, something has to translate these values to types like ints, decimals, enumerations, and so on. Presentation frameworks can go quite a long way to convert types, but what about non-trivial cases?
What about the web form that has an input for Hour and Minute, and you need to combine them? But “Hour” needs to be a real hour, not 5784. That rule has no business in the Domain Model, as my model cares about DateTime, not about individual Hour Minute values.
For things like invariants and validation, I don’t want my Domain Model stuffed with invalid values that I then have to check after the fact. But stuff a ViewModel with invalid data, no harm done. I can validate that object by itself, and report the errors back to the user in a way that most presentation frameworks have built-in support for. It’s clear that while we’d have to make sacrifices in our Domain Model to make it available in the view, it’s often advantageous to simply break free altogether and embrace a completely separate ViewModel.
Crafting a wicked ViewModel
When crafting a ViewModel in MVC land, there are two main “models” you need to worry about: the ViewModel used by your View, and the ViewModel used in action parameters. When designing a GET ViewModel, I craft the ViewModel to contain only what is needed by the View to display its data, and nothing more. Some folks call these DTOs, some ViewModel, but the idea is that you don’t pass your entities to the View. Create some ViewModel, map your entity to it somehow, and pass the ViewModel to the View. In our current project, we’re using a fluent-y auto-mapped solution, so that we never need to configure our mapping from Domain Model to ViewModel (this should be in MVCContrib sometime soon). The nice thing about this ViewModel is that it can use things like MVC validation and binding technologies, gelling nicely with whatever View framework you’re using.
In the action parameter side, here it really depends if the request is GET or POST. For POST, I have only one action parameter, and this is the same ViewModel type that was used to construct the original form. For GET, my rules are relaxed, and I might use Controller technology to bind actual entities to the parameters, so that I don’t have to manually load them up myself. In any case, I make a hard distinction between what my Controller uses, and what my View uses. I have no issue with the Controller knowing about my entities. But when it comes to the View, it’s generally best to let the presentation/view technology do what it does best and not affect my POCOs.
One nice side effect of this approach is that you can design your ViewModel exactly around each screen, so that one entity could be used on several screens, but you’d never need to compromise on the design of each individual ViewModel. Since each View has its own ViewModel, no other View influences the data it displays. Separation of Concerns circling around again.
Keeping it simple
If you’re in a domain where your domain model can be easily used in your Views, you should take a real, hard look at other ways of making your life easier like the Active Record pattern. But if you’re having trouble dealing with DDD, it often comes with the impedance mismatch between MVC technologies and the quest for POCOs. You’re not doing anything wrong, except trying to force that elegant square peg into that stubborn round hole. By letting MVC frameworks do what they do best, and use mapping to go between these layers, we can shield our model from the concerns of the presentation layer.