The MVC's model

I did have a much longer reply but I don’t want anyone to get lost in details so I’ll try and keep it breif.

The assumption that view == template is imho, too simplistic. It basically removes any reusability of the display logic, because now it’s either in the controller or in the template itself. Of course this is an implementation detail but I consider the view to encapsulate the template and work above it.

I disagree with the idea views in PHP as templates are to simplistic. After all simplicity is a beautiful thing. :stuck_out_tongue:

In a desktop application, View logic could be quite complex. HTML removes much of the burden from us, as we no longer (as PHP programmers) need to render anything, we simply provide declarative documents, send to browser and voila. The only time presentation logic should be required (IMHO) is when deciding whether to show or hide a segment of HTML, include an additional template, etc.

I do agree that a View would encapsulate the template, Smarty is a good example of a View class (although most of us use PHP Alternative Syntax; SImple View class).

However introducing a View class for a pager. I really see views as nothing more than trivial data containers. You could provide an API I suppose, to simplify the assignment of data variables calculated by a model, such as:

$pager = new Pager_View();
$pager->setPageCount($model->getPageCount());
$pager->setPageIndex($_REQUEST[‘index’]);
$pager->setPageLength($_COOKIE[‘length’]);

echo $pager->render();

The view would have it’s template initialized in the ctor() and each method acts as simple getter/setter methods.

Having said all this, I think where we might different is in perspective.

From the point of view of a reusable pager control, it to has the triad of components, MVC.

It’s view, being a simple template. Only truly needs a few variables to render a nice pager navigation control:

  1. Index of active page
  2. Number of pages to show

From here the model could calculate the array of paging indexes to show, based on properties you might provide:

  1. Do you want a balanced pager, for example if you have 25 pages and you only show 5 indexes at a time and your current page is 10, do you want output to be:
8 | 9 | 10 | 11 | 12
  1. Do you want a simplistic pager there the active page is always the first index, from the example above:
10 | 11 | 12 | 13 | 14

The presentation logic in the template then would be checking whether to show an enabled or disabled (or whatever else)

HOME | PREV | NEXT | LAST

In this case, the model provides the API, the view remains a simple template. The model does not touch any database directly but whatever table you wanted to paginate would need a model that implemented an interface like Pager.

You could take this a step further an inject the model for the table or file listsings, etc that you wished to paginate, so using the pager, would be as simple as something like:

// Class implements a pager interface 
$model = new File_Listings('../some/path');

// Injecting external model allows pager ctor()
// to initialize it's own model with required variables
$pager = new Pager($model);

$pager->setPageIndex($_REQUEST['index']);
$pager->setPageLength($_COOKIE['length']);

echo $pager->render();

If you look into many windowing frameworks that each component (ie: list box, pager, data grid, etc) they all have their own MVC components and the views are relatively simple, no calculating, complex logic, they only decide what to display, where and maybe why? :stuck_out_tongue:

In old school applicaitons, you might have View calculations when dealing with the GDI. For instance I remember (trying) building a WYSIWYG editor and having to calculate where each character was to be positioned, adjusting line heights, etc. Working directly with the GDI this was nessecary as it did not make sense to go in the model, which would have coupled the already complex model (but possibly reusable) to the WIndows GDI API.

In PHP we do not really have that concern, the View is somewhat implied and handled for us.

I would say Views (especially complex Views) in PHP are probably a sign of over-engineering, IMO.

Cheers,
Alex

The assumption that view == template is imho, too simplistic. It basically removes any reusability of the display logic, because now it’s either in the controller or in the template itself. Of course this is an implementation detail but I consider the view to encapsulate the template and work above it.

Pagination, as we’ve discussed already, is a good example. The logic is the same for every single view. Both the template and the model used can be swapped and the pagination logic reused.

I have 3 views in my system which handle 99% of cases. Forms, Pagination and Generic (which I just assign variables/arrays/objects). I pass them a View Helper (in the Java sense rather than the [url=http://framework.zend.com/manual/en/zend.view.helpers.html]Zend sense) and the template they’re going to use.

I do not deal with pagination by creating a single pagination component. Pagination exists as a set of variables which are transformed into HTML by logic in the View, and into SQL by different logic in the DAO. These variables are not logic, they are data. It is logic which transforms this data into either HTML or SQL. I do not have to change any model definition to deal with pagination. The necessary logic has been defined in one place and is inherited by all model classes.

Haha, I point you to my post above where I anticipated you saying exactly this: talking about your own irrelevant implementation and saying you only need to change the base class.

So you have display logic in the model! Even if you have to change the base model class you’re still changing the model! Take my example where pagination does not exist in the system at all. You’ve just had to modify the model base class to account for it. you are coding your model around how it could be displayed.

I disagree. 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.

To work out the total number of pages you need to:
-Query the database using a count(*) query with the same WHERE as you’re using to fetch the current page
-Calculate $totalRecords / $recordsPerPage

This is logic. However you want argue this, it’s not data. You’re working something out. It’s also only ever going to be used by the view. It’s display logic.

I do not build a view so that it can only be used by one model. I allow my models to use any view, and I allow my views to be used by any model.

This is where you’re very confused. You have things in the model which are related to a single view that may or may not ever use the model. This is wrong, plain and simple. You appear to be blinded by what your code can already do to see the disadvantages of it. Either that or you’re trying to defend it because you don’t want to admit when you’re wrong.

No, I am not changing my position. The data flows between the Model and the View, but how it flows is not specified in MVC.

I do not deal with pagination by creating a single pagination component. Pagination exists as a set of variables which are transformed into HTML by logic in the View, and into SQL by different logic in the DAO. These variables are not logic, they are data. It is logic which transforms this data into either HTML or SQL. I do not have to change any model definition to deal with pagination. The necessary logic has been defined in one place and is inherited by all model classes.

I disagree. 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.

I have never disagreed with this. I have stated quite categorically that in my implementation that any model can be used with any view, and any model can be used with any controller. Tell me where I have said otherwise?

The view has access to the data from the model, but how it is accessed, either directly or indirectly, is not specified in MVC. That is an implementation detail.

I never said that it didn’t. It may do, it may not. But if I show you an MVC diagram which does not have an arrow between the controller and the view, how is it possible for the controller to access the view?

I do not build a view so that it can only be used by one model. I allow my models to use any view, and I allow my views to be used by any model.

That was a significant part of the debate in the previous pages. Whether the controller acting as a mediator nullifies MVC. In a traditional paradigm the view directly communicates with the model and doesn’t rely on the controller to load it with data. I see why given the difference in environments that approach emerged but its not part of the flow of the traditional pattern.

Just out of curiosity, using psuedo-code can someone show me what and how the view would have direct access to the models? Are you injecting the model into the view or is the model a concrete dependency of the view class? Would this not mean you would need a View class for almost every model? How do you query the model within the view, if the model requires GPC, SESSION or SERVER variables? Do you pass those variables into the View via it’s API or do you access those directly from within the View?

Cheers,
Alex

A model doesn’t have to be of the same “entity” as the view. You could have one or several models loaded into a single view. So you could theoretically have separate model classes for the session, server, etc data access and merely inject them into the view. The idea behind a model is data access and that doesn’t specifically only include the database but all data related transfer. Therefore, it is perfectly acceptable to use session and server models. You could even encapsulate that functionality in a single model called system or something.

I never said that MVC does not specify data flow, what I did say is that the mechanics of that data flow - who does the pushing and who does the pulling - is an implementation detail which is not specified in the pattern. The data has to flow between the various components so that each one can do its work, but how the flow is implemented is unimportant.

I repeat (for the umpteenth time) that display logic is the program code which generates the HTML output, not the data which may be incorporated into the HTML output. There is absolutely no HTML code generated within the Model or DAO, so there is no display logic in the Model or DAO. Having a piece of data in the Model or DAO which is passed to the View so that it can be incorporated into the HTML output is not the same as “display logic”. Logic is code, not data.

If the Model contains any data which is passed to the View and incorporated into the HTML output, are you saying that this data is “display logic”? What if this data is obtained from the database? Is this data also “display logic”? If you think about that for a moment who should see the error in your argument. Logic is code, data is not code, therefore data is not logic.

You may think that it’s wrong to generate variables in the Model that are not used in the Model, but which are passed to the View, but where does that rule exist in the definition of MVC?

I agree, push/pull is an implementation detail. Which component does the pushing and which does the pulling is also an implementation detail. The only “requirement” in MVC is that the data flows (somehow) into the right component so that it can be dealt with by that component. You seem to want a definition which is more restrictive than this, and my argument is that I am not prepared to go along with your artificial restrictions.

The Model does not generate any HTML output, therefore there is no dsplay logic in the Model. Logic is not data, it is the program code which operates on that data.

They were not drawbacks (ie. errors) in my methods. You were stating that my approach is wrong simply because it is different from yours.

You keep telling me that my Model contains display logic when it most certainly does not. Logic is code, not data. “Display logic” is that code which generates the HTML output. There is no code in my Model which generates HTML output, therefore there is no display logic in my Model. There is data which is passed to the View so that it can be incorporated into the HTML output, but it is a fundamental requirement of MVC that data flows between the Model and the View so that each component may operate on that data in order to carry out its designated responsibilities. The Model obtains data by unspecified means, then passes that data to the View where it is transformed into HTML.

Now you are contradicting yourself. You stated previously (and I agree) that a Model should be able to be used with any View. This implies that the Model should be able to feed any View with the variables that it may need. If a Model needs to be coded so that it only contains variables that are required by a single view then you are creating an artificial restriction. In your own words “the Model should not be aware of the View” which implies that the Model should not need to know the precise list of variables that are required by the current View. The Model supplies the View with all the data it’s got, and it’s up to the View what it does with that data. This approach allows changes to be made to the View without having to change the Model.

When have I ever been impolite? Insistent yes, but never impolite.

sigh I know I said I wouldn’t but I’ll bite.

There are 2 issues here:
-The definition of MVC
-Model content

I’ll address the first one first. You keep saying things like:

You could even have the Controller “pull” from the Model and “push” to the View, but who cares? That the data flows is important, but the actual mechanics are an implementation detail.

Which is not mvc. In MVC the view interacts with the model directly. Now you’re changing your position.

I repeat (for the umpteenth time) that display logic is the program code which generates the HTML output, not the data which may be incorporated into the HTML output. There is absolutely no HTML code generated within the Model or DAO, so there is no display logic in the Model or DAO. Having a piece of data in the Model or DAO which is passed to the View so that it can be incorporated into the HTML output is not the same as “display logic”. Logic is code, not data.

If the Model contains any data which is passed to the View and incorporated into the HTML output, are you saying that this data is “display logic”? What if this data is obtained from the database? Is this data also “display logic”? If you think about that for a moment who should see the error in your argument. Logic is code, data is not code, therefore data is not logic.

Consider this:

You have pagination nowhere in your system so you create a view for it. You should be able to implement it with any model without changing the model definition. In your system (and no, this isn’t an invitation for you to talk about your own framework again) you have to change the model (and before you say it: base class or not, it’s irrelevant) so that it contains the relevant methods (in this case adding a method to get the total number of available pages) for the view you’ve just added. Is this adding logic? Yes. Is this display logic? Yes. You just added it for the sole purpose of making a view work and your view cannot work without it. This is by definition display logic. Now Tony, I know what you’re like, you’re going to say, in a very cleverly worded way something along the lines of “my own framework already supports pagination so it doesn’t matter”. It does. Who knows what views you will need in the future and there’s certainly no way to know what they might need to know about the model!

Your definition of “Display logic” is flawed. It doesn’t have to be used to return an output to be “display logic” if it’s used only by those functions which generate the output it’s still display logic, you’ve just abstracted it slightly.

You may think that it’s wrong to generate variables in the Model that are not used in the Model, but which are passed to the View, but where does that rule exist in the definition of MVC?

I do (in most cases) think it’s wrong, but nowhere did I say this was anything to do with MVC or was defined in MVC. In fact I explicitly stated that in my first post on the subject:

I am not prepared to go along with your artificial restrictions.

I have suggested nothing about MVC other than the established principles.
I have said nothing more than:
-The model has no awareness of the view (although we already know you don’t like this fact) or controller
-The view has access directly to the model
-The controller accesses both the model and the view

Point me to a whitepaper (or otherwise adequate source.) which says anything else.

I have said nothing else in regard to MVC. The fact that you can’t see past the obvious flaws in a model knowing how it needs to be displayed is simply not my problem. This is MVC, they are not ‘artificial restrictions’ it’s how MVC works.

Now you are contradicting yourself. You stated previously (and I agree) that a Model should be able to be used with any View. This implies that the Model should be able to feed any View with the variables that it may need. If a Model needs to be coded so that it only contains variables that are required by a single view then you are creating an artificial restriction. In your own words “the Model should not be aware of the View” which implies that the Model should not need to know the precise list of variables that are required by the current View. The Model supplies the View with all the data it’s got, and it’s up to the View what it does with that data. This approach allows changes to be made to the View without having to change the Model.

How did I contradict myself? The model should be able to use any view. The difference is, you’re coding your models to cater for your views. You need to cater the view to fit the model.

I just want to clarify for anyone trying to separate the wheat from the chaff in this thread that diagrams like this (http://martinfowler.com/eaaCatalog/modelViewController.html) are UML Class diagrams – not Data Flow diagrams.

I’d like to Marston being that polite, even if he never reaches agreement with anyone.

See to me, the model is more about the business logic than the data access, although that is obviously part of it in 95% of cases.

Where I do disagree, is the idea of having a SESSION model or SERVER model or SYSTEM model that centralized access to environement variables.

For one, I think those objects would essentially be getter/setter abstraction objects, nothing more, so I wouldn’t call them models so much as I would very trivial data accessors.

Secondly, while dependencies are expected and required, the less you have, the better of you are.

I guess it comes down to asking yourself, what are the odds I am going to use this model inside a CLI script? If the answer is yes, then maybe directly depending on SESSION variables isn’t a good idea, at least inside the model?!?

Secondly, what implications does that have on unit testing? Models are the one entity I would test, if and when I write AUT for anything. So the easier time I have, the better.

Anyways, I went slightly off-topic. I am more curious to see what others (including yourself) say about the number of additional view classes that need be introduced. In my applications, the view is typically nothing more than a Smarty instance or PHP alternative syntax custom class.

I assign various values to the ‘view’ object, initialize with a template and render. I use an approach similar to that of Joomla when dealing with complex layouts, so modules like paging are composed of loosely coupled MVC components but you still retain that drop-in nature.

Cheers,
Alex

Hi…

You’ve pretty much got it. Using $_SESSION directly will make a right mess of things.

You’ve already mentioned testing. For unit testing you’re completely knackered, because the tests will start interfering with each other. The key to testing is isolation and repeatability. If you have those, then tests are trivial to write and run as fast as the processor will go. With a free floating $_SESSION you’ll spend your time debugging your tests. Hardly what you want.

The properties that make it good for testing are also good properties for flexibility. If you decide to move a persistent piece of data from $_SESSION to $_COOKIES you end up rewriting code. That can’t be right? An application level presentationish thing causing model rewrites?

Grab hold of $_SESSION right at the very first top level script and pass it down (either as hash or wrapper) forever more. If in doubt always pass it, or better yet pull from it what you need and pass that instead.

The real reason is that if you access $_SESSION directly you’re head will soon explode.

Suppose you have a bug. Another developer offers to help you out, but does not understand the code. They set up everything in a known state and stick a few print statements in to see what is happening. They dig as far as a model returning something strange. Thus far they’ve only have to search the model code, a smallish chunk of application. The bug is somewhere in there and they just have to keep digging downward.

When they hit $_SESSION though, all hell breaks loose. Now the bug could be anywhere in the entire application. the best they can do is start grepping (a painful way of finding dependencies) hoping to find where the session variable got clobbered. Routine fault tracing has turned into spaghetti hell.

That developer that knows nothing about the code is you in a month or two. You can probably see yourself crying into your coffee even now. Listen to the ghost of Christmas future and please, please take that $_SESSION reference out now.

yours, Marcus

Ah stuff this, I’m going back to spaghetti and tables

[ot]

:lol:[/ot]

By “confusing” I assume you mean that I have been putting forward a different, but perfectly valid, opinion.

It means that data flows in the direction of the arrow, but it does NOT dictate whether the data is pushed or pulled, or who does the pushing or the pulling.

That implies that half the things I say are right. Can I quote you on that?

I disagree. To implement MVC you must have three components, each of which performs the responsibilities of either Model, View or Controller. How the data passed between those components, whether it is pushed or pulled, or who does the pushing and pulling, is not the issue - that is an implementation detail.

How many times have you stated that “if its not done this way then it’s not MVC”? I have always worked with a loose definition of MVC, and not one which tries to enforce a particular set of implementation details.

Where exactly did I say that? I even specifically tried to avoid discussing implementation details that weren’t directly relevant.

If anything I said the opposite…

The only thing I’ve been saying is correct is that MVC [url=http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller]dictates [url=http://faculty.washington.edu/hanks/Courses/560/s06/Handouts/mvc_observer.pdf]data [url=http://www.phpwact.org/pattern/model_view_controller]flow

How this is done is a point of discussion (push/pull) and an implementation detail. I will, of course, argue that my preferred way is better. But I’ve not said it’s ‘correct’ and all others are ‘wrong’. I have, however, provided my reasoning.

Do I need to start qualifying all my posts with “in my opinion…”?

Anyway, this has gone way too ad hominem for my liking. I’d rather get back to the actual topic.

Guys. Let’s keep it calm, okay? There is no point whatsoever in continuing this way, and it doesn’t do much good to the overall feel on this forum. Let’s be gents.