In the last post we talked about using entities as the models in an MVC application. This approach works well until an application reaches a certain level of complexity, at which point entities as the M in MVC can become painful.
I believe entities exist to serve the business layer. They also have a role in the data access layer, but only because the data access layer has to be acutely aware of entities. The reverse is not true – entities don’t need to know details about the data access layer nor how they are saved in persistent storage. Entities aren’t owned by the UI, or the data access layer. Entities are business objects and are owned by the business layer.
An application that supports a complex business needs a fine-tuned layer of business logic. You know an application is growing in complexity when you uncover scenarios like these:
These types of requirements have a significant impact on the design and behavior of the business layer and its entities. You want all this complicated business stuff in a layer where it is testable, maintainable, and free from the influence of all the infrastructure that surrounds it – databases, data grids, message queues, communication protocols, and the technology du jour. It’s a business layer built with business objects that encapsulate business state and business behavior. It’s the secret sauce that makes money for your company. It’s a rich model of your domain.
So - why wouldn’t we want to use this rich domain model inside of our views? Isn’t it every young view’s dream to grow up and marry an extraordinarily rich, fat model?
Views can grow complex just as quickly as business logic can grow complex. Complex views might exhibit some of the following conditions.
Perhaps you don’t consider these views as super-complex because you build them all the time, but the types of views we are talking about in the above three bullet points do place requirements and constraints on the model. For example, the UI may require a model that can serialize into a JSON or RSS format.
If you share your entities or domain model with the UI layer, you’ll find your business objects have to serve two masters. The requirements from these two masters will pull your business objects in different directions, and they won’t be optimized to fit in either role.
Also, ask yourself these questions about the model for your views:
Complex applications often require multiple models. There is the domain model that encapsulates your company’s secret money-making business sauce, and then there are multiple view models that the UI layer consumes. Somewhere in between is logic that maps data between the various models. This isn’t a new idea, and it was at one time known as the Model Model View Controller pattern.
You might create a model class for each type of view, like a – MovieReviewViewModel, and perhaps all the UI models derive from a base class. The model classes will hold just the state that their respective views require. These classes don’t need behavior – they are essentially just data transfer objects. In a sense, the model classes also become contracts that explicitly describe what the controller needs to put together for the UI, and the view author sees a model with just the information they need.
Of course, building these additional models comes with a price.
It’s up to you to decide if the benefits are worth the price:
“I have created domain entities like Customer, Order, etc. They come out of repository classes backed by NHibernate. I’m wondering if I send them directly to the view or if I create a ViewModel class to hold data. I’m confused by all the terminology”.
I haven’t given a definitive answer, but I hope I’ve given you enough of my opinion to see that the answer depends on the complexity of your application and its long term goals. For forms-over-data applications, passing your entities can be a simple and effective solution. For more complex applications you may need models built specifically for your views to maintain the integrity and maintainability of your business objects.