The MVC's model

Hi,

After reading various topics on this forum and other blog posts on other sites, I’m curious about how a model should look in an application when using the MVC pattern.

In particular, after reading:

[LIST][]Write your own MVC with PHP; and
[
]The M in MVC: Why Models are Misunderstood and Unappreciated.[/LIST]

I too have found that I am guilty of using a “fat controller” within my applications when attempting to use an MVC. I have simply used a model for the purpose of accessing information in the database, whilst is incorrect.I’m pretty sure this idea was based from what I have previously read on the internet in terms of implementing a model.

So, after reading the above thread and blog post, I’m curious of how the model should should be implemented within a application using the MVC pattern.

Would it be possible for anyone to provide, or link me to actual code examples of how it should be implemented, even if only very brief?

Thanks.

2 reasons:

  1. it puts logic in the model which has no reason to be in there.
  2. It breaks reusability. (Now this is not a real world example so it doesn’t really make sense in this case but…) consider this:

The requirements change: I need to add a view where the total number of pages are calculated in a different way.

In some places I still need to use the old view. In one place I need to use the new one.

In your system, I can’t just extend the view and override the calculation function.

I have to: add yet another method to my model base class, create an extension of the view to reference this new function in the model.

You now have two functions in the view doing a similar job.

Ok for pagination it’s not really a problem as the calculation is unlikely to change, however apply this to handing other things, dates, ranges, currencies, etc and it starts to become more apparent.

Once again though, you cannot provide reasoning in favour of putting it in the model. Nor can you provide reasoning in favour of keeping it out the model. I have provided both of these.

This is irrelevant. It still states that the controller does not feed information to the view.

The article I quoted distinctly said “or the controller could specify to the view what has changed.” This allows the Controller to include any values which have changed. It does not state that the Controller cannot include any changed values, or that the View must obtain these values from the Model itself. If it doesn’t explicitly say so then it’s not a requirement.

Look at the following statement:
The phrase “the view clearly must be informed of each change” does not specify how it is to be informed of any changes, so it is presumptuous of you to say othewise. The highlighted words do not indicate imperative statements, therefore they are options, not requirements.

Again you’re inferring too much. When the controller tells the view what has changed, it is telling the view to fetch an updated piece of specific information from the model. It’s not sending that data from the model to the view! There is no need! The view already has access to the model, why would the controller now act as a model?

One of the earlier papers on the subject is this, unfortunately Steve Burbeck doesn’t provide any references but he would almost certainly have been building on this (along with Goldberg and Robson, 1983)

Which agrees exactly with what Burbeck says. Only it does specify that views only ever inquire from the model, and not get passed data from the controller. You are inferring too much from the sentence “or the controller could specify to the view what has changed”. Burbeck’s wording here is perhaps a little vague, but there are plenty of other papers out there on the subject. Read a few of them. They all say the same thing… the view only ever gets data from the model. There is a reason for this: the model is the only place which holds data.

[quote=“TomB,post:14,topic:60345”]

To which you’re inferring far too much. Sometimes the controller may need to request the models state. What it doesn’t do is pass this on to the view. It may tell the view it needs to update but the view gets its data from the model… not the controller.[/quote]
Do the words usually,and/or and may not indicate that these are options and not requirements? Where do you see always and must?

The article I quoted distinctly said “or the controller could specify to the view what has changed.” This allows the Controller to include any values which have changed. It does not state that the Controller cannot include any changed values, or that the View must obtain these values from the Model itself. If it doesn’t explicitly say so then it’s not a requirement.

Look at the following statement:

So the view clearly must be informed of each change to the text so that it can update its display. Yet the model (which we will assume is an instance of String) need not take responsibility for communicating the changes to the view because these changes occur only by requests from the user. The controller can assume responsibility for notifying the view of any changes because it interprets the user’s requests. It could simply notify the view that something has changed – the view could then request the current state of the string from its model – or the controller could specify to the view what has changed.

The phrase “the view clearly must be informed of each change” does not specify how it is to be informed of any changes, so it is presumptuous of you to say othewise. The highlighted words do not indicate imperative statements, therefore they are options, not requirements.

I disagree. I put the calculation of certain variables in places that I deem to be appropriate, and that is where I generate the values for limit and offset which I incorporate in the SQL query.

This is not display logic as it does not directly generate any HTML. It is the production of HTML which defines diaply logic, not the production of data variables which may be incorporated into an HTML document.

You are nitpicking over trivialities. My Models can be used by any View, which means that they contain methods which can be used by any of those Views. If a particular method is not needed it is not called. Why should this be a problem?

Let’s say that we’re both right and leave it at that. As far as I am concerned they are just differences in implementation. My method works for me, your method works for you.

.

Unless you can explain why the logic for working out the total number of available pages belongs in the model, your argument is void

I disagee. Display logic is restricted to that code which directly produces HTML output, and that code exists only in the View which incorporates any data it has been given into the HTML output. The production of data variables which are later incorporated into the HTML output is not display logic. If the Model does not contain any code which produces HTML output then it does not contain any display logic.

Data is not logic, otherwise you could say that when the Model reads data from the database which is then passed to the View then the existence of this data in the Model constitutes “display logic”.

Please re-read what I have said more than once: If you need to redefine your model for the sole purpose of enabling the use of a view you have display logic -logic which is only required for the purpose of displaying the model in a very specific way– in your model. This is display logic, you’ve just abstracted it to the point that it doesn’t need to deal with outputting HTML. If it’s used only by those functions which generate HTML it is clearly display logic. The fact that you’ve abstracted it to separate it out (which is most definitely not a bad thing) does not mean it belongs in the model.

There is no argument here. I don’t know why you continue with this.

Yes. Your model should be usable by any view. It should have an API with generic methods to request its state. It should not, however, contain methods specific to a single view, that contain concepts (such as paginaton) which are related to how it might, one day, possibly be displayed.

I really give up on this one. If you truly cannot see this now you never will. I have explained it over and over and you come back with no real retort other than “No I’m right!”.

Unless you can explain why the logic for working out the total number of available pages belongs in the model, your argument is void. I have provided reasons why it does not belong in the model. Perhaps it should, perhaps I’m missing something obvious. What you haven’t done is actually address this issue, only skirt around it by changing the subject.

It is certainly easier to put this logic in the model (especially when your view is not allowed to choose which data to display from the model…). This could well be a valid reason in smaller systems where you may not have many views, an extra function in the model (all models…) really isn’t going to make any difference.

My point is, you’ve done nothing to argue your own case, only argue against mine.

I have been told time and time again that my opinion that how the data moves between the Model, View and Controller is an implementation detail and not a “requirement” of MVC is totally wrong, and in a private message I have been directed to read How to use Model-View-Controller (MVC) as a “proper” definition of MVC.

I took the time to read that document, and I found that it actually supports my argument. :lol: In the “Basic Details” section it states the following:

In the MVC paradigm the user input, the modeling of the external world, and the visual feedback to the user are explicitly separated and handled by three types of object, each specialized for its task.

  • The view manages the graphical and/or textual output to the portion of the bitmapped display that is allocated to its application.
  • The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate.
  • the model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).

Notice that it concentrates on the responsibilities of the three components, and does nothing but “suggest” how the data may flow between them. Note the use of the term “usually” in the above list, and the phrase “commanding the model and/or the view to change as appropriate.”

In later sections it gives examples of how the flow may be implemented. In the section titled The Passive Model it states the following:

The controller can assume responsibility for notifying the view of any changes because it interprets the user’s requests. It could simply notify the view that something has changed – the view could then request the current state of the string from its model – or the controller could specify to the view what has changed.

The last sentence tells me that it is alowable for the Controller to pull data out of the Model and push it to the View.

In the section titled The Model’s Link to the Triad it states:

Because only the model can track all changes to its state, the model must have some communication link to the view.

The use of the word some tells me that this link can be implemented in a variety of ways, and is not restricted to a single way.

In the section titled The View - Controller Link it states:

both the view and the controller can send messages directly to each other

This tells me that the flow of messages between the View and Controller may be two-way, and is not restricted to one-way.

Note that these are nothing more than suggestions on how the data may be moved in certain circumstances. They are not rules which dictate how the data must be moved in all circumstances.

I rest my case.

Off Topic:

I’ll believe it when I see it.

Exactly. How the contents of the Model is actually displayed is determined by the code within the View where the HTML output is created. The Model does not create any HTML, therefore does not have any display logic. If a piece of logic does not create HTML, or is not in the View, then it is not display logic.

You stated previously that any Model should have the capability of being used with any View. This is what I have achieved, yet you are saying that I’m still wrong. Please make your mind up.

To which you’re inferring far too much. Sometimes the controller may need to request the models state. What it doesn’t do is pass this on to the view. It may tell the view it needs to update but the view gets its data from the model… not the controller.

The last sentence tells me that it is alowable for the Controller to pull data out of the Model and push it to the View.

You stopped your quotation short in order to take it out of context. What it actually says is:

So the view clearly must be informed of each change to the text so that it can update its display. Yet the model (which we will assume is an instance of String) need not take responsibility for communicating the changes to the view because these changes occur only by requests from the user. The controller can assume responsibility for notifying the view of any changes because it interprets the user’s requests. It could simply notify the view that something has changed – the view could then request the current state of the string from its model

The controller tells the view to update from the model It does not query the model and pass the result to the view… which was the only point of contention here.

This tells me that the flow of messages between the View and Controller may be two-way, and is not restricted to one-way.

Yet again, you’re implying I’ve said otherwise. This is another straw man argument. I really wish you’d stop.

Working out the “total number of pages” requires logic… why should the model have a concept of a “page”? It’s no concern of the model how it may be displayed.

I have things in the Model whch can be used by any View, not just a single View. All possible variables are made available, and it’s up to each individual View whether it uses all those variables or not. This is not confusing to me, nor does it have any obvious disadvantages.

They can be used by any view, but wont. Any logic regarding “pages” will only be used by the pagination view. What about your other views? Do you have logic related only to them in the model too? Your model could potentially become huge.

I am a programmer. I consider the work of people like Trygve Reenskaug, Martin Fowler, Eric Evans, etc. brilliant, while I consider much of my own work cr*p. That is while I spend more time trying to understand what they are saying, and less time telling people about my own code.

So there appear to be at least two kinds of programmers…

So I’m just like every other programmer, then, who thinks that his work is brilliant while the work of others is cr*p. :slight_smile:

I disagree. Display logic is that program code which creates the HTML output, and that program code only exists in the View. Just because I have a piece of data which is passed from the Model to the View so that the data can be shown to the user does not mean that the data, when it is in the Model, is part of the display logic. It is data, not code.

I have things in the Model whch can be used by any View, not just a single View. All possible variables are made available, and it’s up to each individual View whether it uses all those variables or not. This is not confusing to me, nor does it have any obvious disadvantages.

Hi…

He’s on my ignore list and I still can’t help myself :(.

Logic is lines of program code while data is groups of variables. Code is not data, therefore variables are not logic. Data may be transformed, processed or manipulated by logic, but it is not part of that logic.

Every 18 year old CS student knows that this is bogus. Code and data are completely interchangeable.

Code is data when it’s not being interpreted. Data is code if it will be acted upon. The obvious examples are interpreters, compilers, configuration files, declarative languages, queries, bytecode, refactoring tools, blah, blah.

The turing machine makes no distinction between code and data and neither does lambda calculus. Linux makes a distinction (code, data, stack segments) for kernel security and optimisation purposes, but all the PHP code we write will end up in either the data segment or the stack.

As a bit of fun, here is the code for a list structure:


function empty_list() {
    return function () { return false; };
}

function cons($head, $tail) {
    return function ($op) use ($head, $tail) {
        return $op($head, $tail);
    };
}

function head($list) {
    return $list(function ($head, $tail) { return $head; });
}

function tail($list) {
    return $list(function ($head, $tail) { return $tail; });
}

The code above does not assign a single variable.

The cons() function creates a list by prefixing an existing list with an item. So to create an single item list:


$list = cons('hello', empty_list());

A two item list would be:


$list = cons('hello', cons('world', empty_list()));

You can verify that this works by plucking out the second item:

print head(tail($list));

You can even write a function to display the list like so…


function show_list($list) {
    if (head($list)) {
        print head($list) . ' ';
        show_list(tail($list));
    }
}

So you can now go:


show_list(cons('hello', cons('world', empty_list())));

Where is the data? You could compile the above line of code on Linux without ever using malloc().

Funky eh?

yours, Marcus

p.s. The example comes courtesy of Alonzo Church.

A lot of points there.

Take a look at my post here:

I included a very basic example of why repeatable view logic is useful. Otherwise you end up with repeated code in the controller.

If the controller is interacting directly with the template, you end up with something like this (especially where something like smarty is used and you dont have any php code in your template).

Take my previous example:


$perPage = 10;
$page = $_GET['page'];
$users = $this->user->find('lastlogin < "2009-05-10"', $perPage, $perPage * $page);
$totalPages = $this->user->count('lastlogin < "2009-05-10"') / $perPage;
$this->template->assign('users', $users);
$this->template->assign('page', $page); 


Of course you still need logic to create the HTML for the page list.

Something like (pseudo code)


for ($i = 1; $i < $totalPages; $i++) {
$this->template->append('page', array('num' => $i, 'class' => ($i == $page) ? 'current' : '');
}

This is all logic which is repeated anywhere you have pagination. If you create a view class as an intermediate step, this is reusable.

With that intermediate step, all you need is something like I showed in my previous example. It removes all the display logic out of the controller. All the controller is now doing is setting up the view.