7

I've been working with the MVC pattern for a while now, but I honestly don't feel like I truly understand how to work with and apply the "Model" ... I mean, one could easily get away with using only the Controller and View and be just fine.

I understand the concept of the Model, but I just don't feel comfortable applying it within the pattern... I use the MVC pattern within .NET and also Wheels for ColdFusion.

"the Model represents the information (the data) of the application and the business rules used to manipulate the data" - yes, I get that... but I just don't really understand how to apply that. It's easier to route calls to the Controller and have the Controller call the database, organize the data and then make it available to the View. I hope someone understands where my confusion resides...

I appreciate your help in advance!

dcolumbus
  • 9,596
  • 26
  • 100
  • 165
  • can you explain further how you "organize the data and make it available to the view". Depending how you do this, you may already have a usual implementation of a Model (as Sergi noted), or be easier to suggest improvements (like Ben's answer). – richaux Jun 07 '11 at 07:05
  • Let's say a call is made to: /user/login ... the route is called and the User controller has an action called "login" . At this point I can do all the logic within the login action (check DB for user and authenticate them) and then present the result in the View. If I understand what everyone is saying, I should have a "User" model that has functions within it to handle the various tasks like, "userLogin", "userUpdate", and whatever else a "User" might want to do site-wide? – dcolumbus Jun 07 '11 at 07:06
  • I think your question is more about object-oriented programming then MVC. You need to grasp object-oriented programming first, and then worry about what MVC is for. – BobTurbo Jun 07 '11 at 07:15
  • No, that's not it at all. I understand how to work with Objects. I need to understand how to organize the MVC pattern. – dcolumbus Jun 07 '11 at 07:26
  • Your `User` model shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects. Let your LoginController (or LoginService, or whatever) take care of the business logic, then fill a User object with data about the logged in user and pass it to a view for display. Ta-da! You got yourself a model class: the `User`. – Sergi Papaseit Jun 07 '11 at 07:54

6 Answers6

4

Look at it like this. When your client requests a page this is what happens (massively trimmed):

  • He ends up at your controller

  • The controller gets the necessary data from your model

  • The controller then passes the data to the view which will create your HTML

  • The controller sends the HTML back to the client

So client -> controller -> model -> controller -> view -> controller -> client

So what is the model? It is everything that is required to get the data required for you view!

  • It is services

  • It is data access

  • It is queries

  • It is object mapping

  • It is critical 'throw exception' style validation

Your controller should not be writing your queries if you are sticking to the pattern. Your controller should be getting the correct data required to render the correct view.

It is acceptable for your controller to do a few other things such as validating posted data or some if/else logic but not querying data - merely calling services (in your model area) to get the data required for your view.

BritishDeveloper
  • 13,219
  • 9
  • 52
  • 62
  • 1
    This is how I'm beginning to understand the Model... but then @Sergi Papaseit mentions that there shouldn't be anything more than placeholder attributes of an object. I'm beginning to think that there really is no clear understanding... – dcolumbus Jun 07 '11 at 19:01
  • @dcolumbus - The model is vast, though... many layers in and of itself. It's not that there is no clear understanding. There is just not one "right" way to do it. @BritishDeveloper's overview is accurate. The controller "organizes" the app. The view displays. The model handles data. How it handles it is subjective. But that's what the model does, in a nutshell. – charliegriefer Jun 07 '11 at 19:08
  • Are you saying that queries should be in the Model? – dcolumbus Jun 07 '11 at 19:08
  • Yes, queries should absolutely be in the model. Maybe in a service object in the model. Maybe in a DAO object in the model. Again... it depends on how the model is architected. But queries... definitely in the model somewhere. – charliegriefer Jun 07 '11 at 19:11
  • You mentioned it seems more straightforward to put the queries in the controller. But what if you have multiple methods in multiple controller files that need to do the same thing? Are you going to duplicate that code? Or are you going to call a single method in the model from various places in the controller(s)? That might help illustrate why the queries should be pushed out of the controllers. – charliegriefer Jun 07 '11 at 19:12
1

I suppose it's just what you decide to call the different bits in your application. Whichever class you use to pass information from the Controller to the View can be seen as/called "The Model".

Typically we call Model our entity classes, and we call View Model the "helper" classes, for lack of a better word, we use when a "pure" entity (i.e., one that will be stored in the database) doesn't suffice to display all the information we need in a View, but it is all mostly a naming thing.

Your model classes shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects:

// This would be a model class representing a User
public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

How do you actually pass information (whatever that might mean in your context) form your controller to your View and vice versa? Well then, that's your model. :)

Sergi Papaseit
  • 15,999
  • 16
  • 67
  • 101
  • I added a bit more to my question above ^^ – dcolumbus Jun 07 '11 at 06:45
  • I was still expanding my answer :þ How do our Controllers and Views interact with each other at this point? – Sergi Papaseit Jun 07 '11 at 06:54
  • I commented on my post above ^^ – dcolumbus Jun 07 '11 at 07:43
  • I'm not sure you're going to get a clearer explanation than this one. – Steve Hobbs Jun 07 '11 at 08:23
  • Why shouldnt you have functions in your model classes? This is the method i take and find it really helpful to expand the functionality of my objects away from the simple dumb objects. – namtax Jun 07 '11 at 08:34
  • I'm not saying your models can't have functions, but you should keep the [Single Responsibility Principle](http://en.wikipedia.org/wiki/Single_responsibility_principle) in mind: The model classes carry information, let "business intelligence" bet someone else's responsibility. IMHO, of course :) – Sergi Papaseit Jun 07 '11 at 08:51
  • Ok, just trying to get an understanding. So lets say you have a model object with firstname and surname, and you want a way to display fullname by concatinating firstname and surname, where would you put that method? – namtax Jun 07 '11 at 10:43
  • @namtax - I would override the `ToString()` method of the model ;) But assuming this is just a simple example, I would probably opt for an HtmlHelper extension method. If you were to literally make this small method it wouldn't hurt to put it in the Model itself. – Sergi Papaseit Jun 07 '11 at 11:07
  • Ok, that seems fair. I guess the htmlHelper method would be used in the view? – namtax Jun 14 '11 at 10:18
1

Here is the way I have explained before:

  • Controller: determines what files get executed, included, etc and passes user input (if any exists) to those files.

  • View: anything that is used to display output to user.

  • Model: everything else.

Hope that helps.

DarthJDG
  • 16,511
  • 11
  • 49
  • 56
Scott Stroz
  • 7,510
  • 2
  • 21
  • 25
0

Model is the code representation of your base Objects. While some less data-intensive systems may be light on the model end of MVC, I am sure you will always find an applicable use.

Let's take a contrived (but realistic) example to the usefulness of a model:

Say I am making a Blog. My Blog has Post objects. Now, Posts are used in and around the site, and are added by many users in the system. Our system was coded for people to enter HTML into their posts, but low and behold, people are starting to add pasted text. This text uses "\n" as the newline character.

With a model, this is a relatively simple fix. We simply make a getter that overrides postText:

public function get postText() {
    return this.postText.replace("\n", "<br />");
}

Suddenly, we can affect behavior across the entire site with a few lines of simple code. Without the implementation of a model, we would need to find and add similar functionality where ever postText is used.

The Model in MVC is all about encapsulation and flexibility of a codebase as it evolves over time. The more you work with it and think about it in this manner, the more you will discover other cases that would have been a nightmare otherwise.

--EDIT (you have added to your question above):

Let us take this same example and use your Controller calling the database. We have 9 Controller classes for vaious pages/systems that use Post objects. It is decided that our Post table needs to now have a delete_fl. We no longer want to load posts with delete_fl = 1.

With our Post model properly implemented, we simply edit the loadPosts() method, instead of hunting down all the cases across the site.

An important realization is that in any major system, the Model is more of a collection of files than a single monolith. Typically you will have a Model file for each of your database tables. User, Post, etc.

Ben Roux
  • 7,308
  • 1
  • 18
  • 21
0
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>

The idea is to separate the concerns. Why not just have the controller logic in the view as well? The model represents the business objects, the controller manipulates those objects to perform some kind of task and the view presents the result. That way, you can swap an entire view for a different one and you don't have to rewrite the entire application. You can also have people work on different layers (model, controller, view) without affecting the other layers to a significant degree.

By combining the controller and the model, you are making your code less maintainable and extensible. You are basically not performing object-oriented programming as you are not representing the things in your database as objects, you are just taking the data out and sending it to the view.

BobTurbo
  • 289
  • 4
  • 14
-1

The model contains business logic (i.e. significant algorithms) and persistence interaction - usually with a database. The controller is the MVC framework: Wheels, Struts, .NET's MVC approach. The view displays data that the controller retrieves from the model.

The big idea going on with MVC is that the view and model should be unaware of the controller - i.e. no coupling. In practice there's at least some coupling that goes on, but when well done should be minimal, such that it allows for changing the controller with low effort.

So what should be happening is a request hits the controller, typically a front controller, where there should be some glue code that you've written that either extends some controller object or follows some naming convention. This glue code has the responsibility for calling methods on the correct service layer object(s), packing that data inside of some sort of helper - typically an Event object - and sending that to the correct view. The view then unpacks data from the Event object and displays accordingly.

And when done well, this leads to a domain model (a.k.a. model) that is unit testable. The reason for this is that you've divorced the algorithms from any framework or view dependencies. Such that you can validate those independently.

orangepips
  • 9,891
  • 6
  • 33
  • 57