Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the usage of Model in MVC? Is it actually useful?

Tags:

I'm new in this, so bear with me. I've been using one MVC framework in a couple of projects lately, and after a while, I'm disillusioned in the perceived usefulness of the 'Model' in MVC.

I get the usefulness of Controllers and Views, I know that separation between presentation and logic is important to make the code more maintainable in the future, although not necessarily faster or more robust.

If all logic should be placed inside the controller in the first place, I don't see any use for Model, especially the Active-Record. We already have a language that is so robust and easy to use to communicate with the database, am I right? It's called SQL. For me when models are implemented like active-record, it's usefulness depends on whether or not you want your app to fit in multiple databases.

So what I'm asking is, if you're only using one database, why bother with Models and Active-Records? Why don't just use SQL? Why the extra layer of complexity? Do you guys have any case studies/real-life stories where models actually can do things better than just using the database class and SQL-away?

Again, I'm sorry if I seem to be so ignorant, but I really don't know why Models are important. Thanks for answering.

like image 259
rickchristie Avatar asked Feb 23 '11 16:02

rickchristie


2 Answers

First, you are assuming that a model layer necessarily uses some kind of ORM, in order to abstract SQL away. This is not true: you may create a model layer which is loosely-coupled from the Controller layer but tightly-coupled to a particular DBMS, and so avoid using a full-featured ORM.

There are some ORM libraries, like Hibernate (Java), NHibernate (.NET), Doctrine (PHP) or ActiveRecord-Rails (Ruby) that really can generate all actual SQL statements for you; but if you think ORM is unnecessary, and you want to define all SQL statements by hand, don't use them.

Still, IMHO this does NOT mean you should just place all you DB related logic inside the controller layer. This is called the "fat controller" approach, and it is a road that leads, many times, to bloated, unmaintainable code. You could use it for simple CRUD projects, but anything beyond that will demand the existence of a real "Model".

You seem to care about MVC. Please, read also something about TDD. A wise man once said "legacy code is code without tests". When you learn that automated unit tests are as important as the "real" code, you will understand why there are so many layers in an enterprise application, and why your Model layer should be separate from the Controller. A block of code that tries to do everything (presentation, business logic, data persistence) simply cannot be easily tested (nor debugged by the way).

Edit

"Model" is a little bit fuzzy term. Depending from where you look at, it can mean something slightly different. For instance, PHP e Ruby programmers frequently use it as a synonym to an Active Record, which is not accurate. Some other developers seem to believe that a "model" is just some kind of DTO, which is also not right.

I rather use the definition of model as seen in Wikipedia:

The central component of MVC, the model, captures the application's behavior in terms of its problem domain, independent of the user interface. The model directly manages the application's data, logic and rules.

So the Model is the biggest, most important layer in most MVC applications. That's why it is usually divided in sub-layers: Domain, Service, Data Access and so on. The Model is usually exposed through the Domain, because it's there where you'll find the methods that your controller will call. But the Data Access layer belongs to the "Model" too. Anything that is related to data persistence and business logic belongs to it.

like image 62
rsenna Avatar answered Nov 04 '22 07:11

rsenna


In most real-life situations, data that comes from the user doesn't go straight into the database.

It must often be validated, filtered, or transformed.

The role of the model layer is usually to make sure that data arrives properly into the backend store (usually the database) by performing these operations, which should not be the responsibility of the controller (skinny controller, fat model), and not the responsibility of the database engine itself.

In other words, the Model layer is responsible - or `knows' - how the data should be handled.

Most modern MVC frameworks provide ways to specify contracts over the data validity requirements, such as Rails.

Here's an example from http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/:

class Cat   validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'   validates_inclusion_of :vaccinated, :in => [true,false]   validates_inclusion_of :fiv, :in => [true,false]   validates_inclusion_of :age, :within => 1..30   validates_each :weight do |record, attr, value|       record.errors.add attr, 'should be a minimum of 1 pound' if value and value  /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/   validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500 end 

Here, several of the data validity requirements cannot be handled by the database, and should not be handled in controllers, because any modification in those requirements might break the code in several places.

Therefore, the model is the best place to make sure data is coherent for your domain.

There's a lot more to be said about it, but I felt like tackling a point that seems important to me, motivated by practical experience :)

like image 29
SirDarius Avatar answered Nov 04 '22 07:11

SirDarius