Skinny Controllers and Fat Models
Most of the modern web application frameworks follow the MVC design pattern. It’s probably one of the most misunderstood design patterns in existence. There are a lot of discussions what kind of responsibilities each letter holds. Common misinterpretation in MVC is regarding the letter M.
The Model should be understood as a domain model. Meaning a collection of domain objects. Usually an application has one model that is the domain model. Models are often mistakenly referenced to as singular domain entities. For example an Order, a User or an Account. This leads unwary developers to common application design problems.
It’s common to see a web application to have a directory named “models” with class files inside it. Upon closer inspection one can often find that those classes are the nouns of the application. For example those nouns could be a User, an Order or a Product. In this scenario the MVC Model stands for singular application entities.
Problems start to surface when an application developer has to create reports, do input validation or to implement an ACL. These kind of problems don’t naturally fit into entities. For example getting a report of top 10 products doesn’t naturally fit into any entity. Validating a complex search filter made out of multiple input fields also doesn’t fit into any of the entities.
It’s common to see developers adding logic that doesn’t fit anywhere naturally to controller classes or somewhat close entities. For example adding a top 10 products report to an Order entity class as a static method call. Or validating complicated search filters inside controller actions.
In time this steadily leads to bloated controller and entity classes that later on become fat spaghetti dishes. Controller classes containing thousands of lines of code with more private methods than public ones, entity classes with few state changing methods and hundreds of lines long SQL report queries with joins to 10 tables.
To prevent this from happening it is crucial to understand what controller and model stands for. A controller’s responsibility is only to receive input and initiate a response for the view by making calls on model objects. This means that controllers should be very light and skinny. Usually doing nothing else just instantiating classes, getting data from the domain objects and passing it to the view. Model is not a singular entity and can consist of an entire web of interconnected domain objects. The definition fat model means having as many domain objects as needed. Be it reports, validators, filters, entities, strategies and so on.