Page 1 of 2

how should the model communicate its result?

Posted: Thu Nov 20, 2008 12:39 am
by koen.h
Think fat models thin controllers. As much as possible is done in the model. How does the model communicate the result of its operations to the controller?

One example is zend_auth. The model could give a result object back to the controller. What about other scenarios? Eg a model that also tests for allowed characters? Or an update to the database that somehow went wrong? What's the standard way in dealing with these?

Maybe in general terms the question is: How to deal with model to controller communication that goes beyond model->getObjectById(10)?

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 1:34 am
by Christopher
I think of the Controller as mostly accessing methods like isValid() or isError(), whereas the View would access methods like findSaleProducts() or getTotal(). That sounds like the Controller is looking more for state, while the View is looking more for values.

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 2:13 am
by koen.h
arborint wrote:I think of the Controller as mostly accessing methods like isValid() or isError(), whereas the View would access methods like findSaleProducts() or getTotal(). That sounds like the Controller is looking more for state, while the View is looking more for values.
So what you suggest is that the model contains the appropriate methods that the controller can use to (re)direct workflow? Eg controller tells model to do something, [model doesn't return something], controller checks state via model methods, controller decides next action based on state (eg if all ok display view).

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 2:51 am
by Christopher
Yes.

It is somtimes a fine line. For example I would rather see the Controller checking state:

Code: Select all

if ($model->hasProducts() ) {
Than letting a little business logic creep into the Controller, such as:

Code: Select all

if ($model->getNumProducts() > 0) {
It may seem a small difference, but the less the Controller has to know about the Domain the better. The View, on the other hand, could certainly use getNumProducts() to display the value or loop through product records.

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 7:35 am
by josh
If it's something like a comparison operator, like > < >= >= != !== or ===, you could do it inline and have it arguably 'read' better*, however the 3rd time you repeat yourself most will agree the logic should be encapsulated into the class. I think the controller would ask the model the minimal amount of info it needs to get the least amount of coupling. The controller might ask the model if it is valid and redirect to an error action, an error action might ask for an error collection from the model and assign it to the view, and render an error view that takes care of displaying the errors.

* if you are using it one or 2 places the extra indirection of encapsulating the comparison can not be worth it

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 7:47 am
by koen.h
jshpro2 wrote:If it's something like a comparison operator, like > < >= >= != !== or ===, you could do it inline and have it arguably 'read' better*, however the 3rd time you repeat yourself most will agree the logic should be encapsulated into the class. I think the controller would ask the model the minimal amount of info it needs to get the least amount of coupling. The controller might ask the model if it is valid and redirect to an error action, an error action might ask for an error collection from the model and assign it to the view, and render an error view that takes care of displaying the errors.

* if you are using it one or 2 places the extra indirection of encapsulating the comparison can not be worth it
If I understand you correctly you also say it's good practice that the model has methods that the controller can use to interrogate about it's [the models] state. Not having the model give a result class with info back (like zend_auth_result)?

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 8:23 am
by josh
It depends, if your controller is doing too much heavy lifting that is a sign there is a new object begging to be born

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 8:58 am
by koen.h
jshpro2 wrote:It depends, if your controller is doing too much heavy lifting that is a sign there is a new object begging to be born
I agree, though I'm more interested (in this post) in what the best way is for the model-controller to communicate. You gave some pointers and I think you hinted at the model having state-revealing methods for the controller to use.

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 11:27 am
by josh
What do you mean communicate? If you're pulling back heavy data out of the model you probably want to break up the actions or create controllers to specialize in certain things, it will help you out in terms of avoiding duplication. It is probably indicative of a god class at the top of the model hierarchy. Judicious application of refactoring will cure it.

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 1:16 pm
by Christopher
jshpro2 wrote:... you could do it inline and have it arguably 'read' better*, however the 3rd time you repeat yourself most will agree the logic should be encapsulated into the class.
I think this is why 'read better' is not a reason to implement a certain way, because often 'read better' implies more information is provided by the code. I am proposing that 'reading worse' means less information about business logic leaking out of the Model. If the programmer wants more information that the minimum -- they should go look in the Model.

PS - I am often a proponent of what might be called 'worse is better' in design...

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 2:45 pm
by josh
I agree, don't get me wrong I'm all for encapsulation, and if you know you're going to be duplicating it go ahead and encapsulate it off the bat. A purist will tell you classes should self encapsulate their own fields as in $this->getPrice() instead of $this->price. While its no doubt encapsulation is always preferred :D if you're not a purist you can let things slide, although arborint is right, let stuff slide too much and you'll slide right off the cliff :lol:

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 4:24 pm
by Christopher
It's not just encapsulation that I am thinking about, such as $this->getPrice() instead of $this->price. It's about where those little business rules exist. Say for example that orders over $100 get free shipping. I would much rather see $model->isFreeShipping() than to have ($model->getPrice() > 100) somewhere. The Controller or View may want to do something different if shipping is free, but it should not have any knowledge of how "free shipping" is determined. That's the difference with dealing with state and dealing with values to me. Then if I want to change the free shipping level to $200 that rule hasn't leaked out of the model. So I would suggest forcing yourself early to keep business logic in the Model. Even if it seem trivial, do it anyway.

Re: how should the model communicate its result?

Posted: Thu Nov 20, 2008 4:36 pm
by josh
Well encapsulation is one thing ( as in checking the comparison ) but if you're going to define a conditional business rule that should most definitely be defined as a method on the class itself. The special case pattern may of interest here if the logic gets unwieldy

Re: how should the model communicate its result?

Posted: Fri Nov 21, 2008 12:05 am
by alex.barylski
What's the standard way in dealing with these?
I don't know if Zend has tried to standardize this but in my experience how you deal with the model in a controller or a view will depend on your own requirements.

If your View uses the model directly you introduce a dependency. This would make sense if your view is something like a list box which is always populated the same and used in many "pages". If it isn't I would keep the model/view relationship more abstract and pass the results from the model to the view inside the controller.

It also depends on how you implement a view and or model...so yea...many factors to consider before I would commit to any one single approach.

Cheers,
Alex

Re: how should the model communicate its result?

Posted: Fri Nov 21, 2008 12:54 pm
by VladSun
Another question that bothers me - do we need an Action Controller at all? Isn't it the Front controller enough for building a web MVC application?
These "thin controllers" look too much similar to each other, so why not put'em into the Front controller?

If we have an interface that every Model object should implement, I don't think we need any control flow logic in the Action Controller.