In a MVC application, should the controller or the model handle data access?

26,326

Solution 1

All business logic should be in the MODEL.

Remember, the responsibilities of each layer are thus:

  • Controller - bridge between the model and view. Decides where to go next.
  • View - displays the data, gathers user input
  • Model - business logic, interface to data store.

One of the biggest gains is in maintenance and (later) expansion. In general:

  • If you need to change business logic, you should not need to modify your controller or view.
  • If you change your visual display, you should not need to modify your model or controller.
  • If you change your workflow, you should not need to modify your view or model.

To do the above, each layer should have no knowledge of the others in order to work properly. For example, the view should receive its data and not need to know anything about where it comes from in order to display it properly. The controller should not need to know anything about the underlying structure of the model in order to interact with it. The model should have no knowledge of how the data is to be displayed (e.g., formatting) or the workflow.

"He also believes that any call that returns a Json object should happen in the model, not in the controller. The model would return an array to the controller, which would then return this as a Json object."

NO. The Model should never format data. It also should not read formatted data. That is polluting the model and moving into the level of hell where business logic = display logic.

JSON (coming in or going out) is just another view. So going out:

Data Store -> Model -> Controller -> View

Coming in:

View -> Controller -> Model -> Data Store

Solution 2

FYI, my primary language is PHP, so you can take this all with grain of salt.

The business business logic in MVC and MVC-inspired patterns has to be in the model layer. And yes, model is supposed to be a layer, not a class or object.

Most of said logic would reside in the domain objects, but some of it would end up in services, which should at like "top-level" structures in model layer, through which presentation layer (views and controller) interact with model layer.

Services also should facilitate the interaction between storage abstractions (data mappers, data access objects, units of work and/or repositories) and the domain objects. These structures would deal with persistent and temporary storage and deal with data integrity.

This sort of separation simplifies both the maintenance and testing of the codebase. You gain the ability to easily test you domain logic, without ever touching database (or any other form of storage.

Controllers (and the equivalent structures from other MVVM and MVP patterns) should be extracting information from user's request and changing the state of model layer (by working with services) and the view.

If you implement MVP or MVVM, then the controller-like components would have additional responsibilities, including data transfer from model layer to view, but in classical and Model2 MVC patterns the view is supposed to be an active structure, which request data from the model layer.

As for generation of JSON, that actually should happen in the view. Views are supposed to contain all (or most, depending on how you use templates) the presentation logic. It should acquire information from model layer (either directly or though intermediaries) and, based on that information, generate a response (sometimes creating it from multiple templates). JSON would be just a different format of response.


There has be huge impact (and mostly - negative) by Rails framework, which was released in 2005th. The original purpose of it was to be a framework for prototyping - to quickly create a throw-away code. To accomplish this they simplified the pattern to the point where the separation of concerns was broken.

They replaced model layer with collection of active record structures, which easy to generate and merged the view functionality in the controller, leaving templates to act as replacement for full blown view. It was perfect solution for initial goal, but, when it started to spread in other areas, introduced large number of misconceptions about MVC and MVC-inspired design patterns, like "view is just a template" and "model is ORM".

Solution 3

Your controller methods should be as thin as possible, which means that data access belongs in the model (or more specifically, a Repository object).

Think of your controller methods as a switch-yard... they are only responsible for delegating tasks to other methods for execution.

If you are writing any Linq code in your controllers, you are creating a dependency that will have to be modified if your site structure changes, and you are potentially duplicating data access code. But GetCustomer in the model is still GetCustomer, no matter where you're calling it from your Controllers. Does that make sense?

Business logic that is more extensive than simply accessing data can be put into its own Business Logic Layer, which is considered part of the Model.

I'm not so sure about the JSON. JSON is just an alternative data representation; if you have a utility method that can transform your data classes to JSON, call GetCustomer from the Model, and perform the transformation to JSON in your controller method.

Solution 4

The Model should handle data access.

From MSDN:

Models. Model objects are the parts of the application that implement the logic for the application's data domain. Often, model objects retrieve and store model state in a database. For example, a Product object might retrieve information from a database, operate on it, and then write updated information back to a Products table in a SQL Server database.

Solution 5

In MVC, the model is responsible for handling data access. The pro is that all data access code is encapsulated logically by the model. If you included data access code in the controller you would be bloating the controller and breaking the MVC pattern.

Share:
26,326

Related videos on Youtube

Scottie
Author by

Scottie

Updated on January 28, 2020

Comments

  • Scottie
    Scottie about 4 years

    We are having some philosopical debates in our company about where the calls to the Business Logic should be to perform CRUD operations.

    I believe that the Model should consist of your data structure and that the controller should be responsible for populating the data.

    My co-worker believes that all population should be done in the model class itself, and simply called by the controller. This keeps the controller neat and clean (but, in my opinion, clutters up the model).

    He also believes that any call that returns a Json object should happen in the model, not in the controller. The model would return an array to the controller, which would then return this as a Json object.

    What are some different pros/cons to each and is there a right or wrong way to do this?

    • nawfal
      nawfal over 9 years
      Good q. Letting us know what type of project/framework/platform you are on should help us better.
  • Scottie
    Scottie over 11 years
    Thanks for all the great comments. Hard to choose a single "correct" answer, as they are all correct, but Bryan seems the most complete.
  • Admin
    Admin over 7 years
    "Model - business logic, interface to data store" and "The Model should never format data. It also should not read formatted data." So what happens when you have json data that you need to add to a database? Obviously the Model in your logic should not accept is as such, json. So it should be reowrked. By whom? By an interface into the Model. But you just stated that the interface is .... the "Model ... (is) interface to data store". There is at least a seeming contradiction there that needs to be resolved or clarified.
  • Ken
    Ken almost 6 years
    Wow sure would be nice to have a small project example of your write up .. I think that would clarify things for me greatly. Even if it was simply name and address sample ..
  • Jeaf Gilbert
    Jeaf Gilbert about 4 years
    In PHP, a model cannot do $stmt->fetch(PDO::FETCH_CLASS, $this). I can cast all the properties manually by $this->id = $object->id, but it could be really long and not easy to maintain (if there are any column changes). Does it mean PHP wants us to do the queries in Controllers? Or is there any proper code to replace: $stmt->fetch(PDO::FETCH_CLASS, $this)?
  • Minh Nghĩa
    Minh Nghĩa almost 4 years
    Many guides on MVC claim that user input must be inside controller though...