How to keep models and controllers in good shape

When I hear “It should be done in this way”, I always ask a question “Why?” Indeed, if everyone believed in design patterns but did not understand it, engineering would be yet another religion.

So what about “Fat model, skinny controller” (and vice versa) in the MVC pattern? Where do controller’s charges end and model’s ones begin?

Well, the main goals of every design pattern are encapsulation, isolation and code reusability. The MVC pattern consists of three parts. Model one responds for business rules and data management. View one­—for model representation in the user interface. And controller one binds model and view, i.e. makes them work together. “Thank you Captain Obvious” you would say, but keep in mind the key point is that model knows nothing about controller and view.

Imagine a typical web application. You carefully implemented HTTP request handling, HTML generation, user session, and other web-related things. If you had been asked by client: “Look, it works great. But we need to interact with the application using RPC protocol. Could you implement it?” Would you have to change the code of your models? Would there be some unusable code? I mean some code, which is used in web only. If you answered “yes”, you should change your design approach.

Model should be reusable in any interface without modification: web, RPC, shell, desktop, mobile—you name it. Therefore any interface-specific code should be placed in controller (or view). By the way, TDD helps to keep model clean. If you test models in isolation, there will be no unnecessary code. Because test environment is yet another interface!

However, there is a nuance—data validation. On one hand, it is clearly model’s job. On the other, it would be a cause of great performance overhead in batch processing from a trusted source. I think, validation layer should be separate from the model one or be switchable. And of course, it should not be mixed with sanitization layer. For example, protecting from XSS attack is web controller’s job. Protecting form SQL injection is model’s one. Validation layer (when it is needed) should be placed somewhere between these two. Solution depends on the task, there is no silver bullet.

In a nutshell, keep models clean and reusable. Would they be fat or skinny? Nobody cares. Make them play sports and they will be in good shape!