Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fat models and skinny controllers sounds like creating God models

I've been reading a lot of blogs which advocate the fat models and skinny controllers approach, esp. the Rails camp. As a result the routers is basically just figuring out what method to call on what controller and all the controller method does is call the corresponding method on the model and then bring up the view. So I've two concerns here which I don't understand:

  1. The controller and router are really not doing much different tasks other than just calling a method on the God-like model based on the route.
  2. Models are doing too much. Sending emails, creating relationships, deleting and modifying other models, queuing tasks, etc. Basically now you have God-like objects that are supposed to do everything that may or may not concern with modeling and dealing with data.

Where do you draw the line? Isn't this just falling into the God pattern?

like image 451
Jungle Hunter Avatar asked Dec 26 '12 18:12

Jungle Hunter


2 Answers

It might not be the best idea to look at Rails as a staple of MVC design pattern. Said framework was made with some inherent shortcomings (I kinda elaborated on it in a different post) and the community only just now has begun addressing the fallout. You could look at DataMapper2 development as the first major step.

Some theory

People giving that advice seem to be afflicted by a quite common misconception. So let me begin by clearing it up: Model, in modern MVC design pattern, is NOT a class or object. Model is a layer.

The core idea behind MVC pattern is Separation of Concerns and the first step in it is the division between presentation layer and model layers. Just like the presentation layer breaks down into controllers (instances, responsible for dealing with user input), views (instances, responsible for UI logic) and templates/layouts, so does the model layer.

The major parts that the model layer consists of are:

  • Domain Objects

    Also known as domain entities, business objects, or model objects (I dislike that latter name because it just adds to the confusion). These structures are what people usually mistakenly call "models". They are responsible for containing business rules (all the math and validation for specific unit of domain logic).

  • Storage Abstractions:

    Usually implemented using data mapper pattern (do not confuse with ORMs, which have abused this name). These instances usually are tasked with information storage-from and retrieval-into the domain objects. Each domain object can have several mappers, just like there are several forms of storage (DB, cache, session, cookies, /dev/null).

  • Services:

    Structures responsible for application logic (that is, interaction between domain objects and interaction between domain objects and storage abstractions). They should act like the "interface" through which the presentation layer interacts with the model layer. This is usually what in Rails-like code ends up in the controllers.

There are also several structures that might be in the spaces between these groups: DAOs, units of work and repositories.

Oh ... and when we talk (in context of web) about a user that interacts with MVC application, it is not a human being. The "user" is actually your web browser.

So what about deities?

Instead of having some scary and monolithic model to work with, controllers should interact with services. You pass data from user input to a specific service (for example MailService or RecognitionService). This way the controller changes the state of model layer, but it is done by using a clear API and without messing with internal structures (which would cause a leaky abstraction).

Such changes can either cause some immediate reaction, or only affect the data that the view instance requests from model layer, or both.

Each service can interact with any number (though, it's usually only a handful) of domain object and storage abstractions. For example, the RecogitionService could not care less about storage abstractions for the articles.

Closing notes

This way you get an application that can be unit-tested at any level, has low coupling (if correctly implemented) and has clearly understandable architecture.

Though, keep in mind: MVC is not meant for small applications. If you are writing a guestbook page using MVC pattern, you are doing it wrong. This pattern is meant for enforcing law and order on large scale applications.

For people who are using PHP as primary language, this post might be relevant. It's a bit longer description of the model layer with a few snippets of code.

like image 96
tereško Avatar answered Oct 21 '22 10:10

tereško


If the "model" classes are implemented poorly yes, your concern is relevant. A model class shouldnt be doing Email (infrastructure tasks).

The real question is what does model in MVC imply. It isnt restricted to POCO classes with a few methods. Model in MVC means Data and Business logic. Treat it as a superset of classic core POCO models.

View ==== Controller ==== Model ---> Business Process layer --> Core models

Throw in Infrastructure assemblies and Data Access layers and use injection to hand that into the BPL then your a process is using MVC as intended.

BPL may invoke UoW / Respository patterns, and execute business rules and call Infrastructure features by way of injected Objects or interface patters.

So the recommendation to keep a controller skinny doesnt mean the "person" class in a classic Core model should have 50 methods, and call Email directly. You are right to think this is wrong.

The Controller May still be required to instantiate and inject Infrastructure classes into the BPL or core layer if called directly. There should be a business layer or at least classes orchestrating calls across Classic Object model classes. Well thats my "view" anyway ;-)

For generic take on MVC the wiki description http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

A Little Blog that talks about the "M" in MVC. http://www.thedeveloperday.com/skinny-controllers/

like image 5
phil soady Avatar answered Oct 21 '22 10:10

phil soady