I'm still trying to wrap my mind around the MVC pattern and exactly what is supposed to be placed in Controllers, and what should be placed in Models. I've read that controllers mostly contain application logic, and models should have all the business logic. It's sometimes hard to differentiate between the two. Where exactly do you draw the line? What types of actions are on the fringe of both?
-
I recommend you take a gander @ http://codeigniter.com/. It's a rather powerful MVC PHP Framework. It will get you accustomed with the MVC Pattern. – Khez Apr 11 '11 at 01:47
3 Answers
MVC is a rather loaded term, it means different things to different authors.
When it was introduced in Smalltalk, controllers were for user input, views were for output, and models were for state related to the problem space.
Apple also uses the term MVC in its documentation for iOS and Mac OS, but there the model is for basically database access/problem space, the view is for both input and output and controllers are for wiring Models and Views together.
MVC is used by others as well, and again the terms mean slightly different things in each case, with the controller being the most variable between them. All this means that answering your question is quite difficult.
In the abstract though, the model should consist of that which a domain expert would understand. The line drawing you talk about has mostly to do with validation of user input which is often put in the controller because the response to invalid input is usually application dependent and often bad input needs to be weeded out before sent off to the model in a distributed system.
Hope this helps somewhat, but the question itself is vague, so the answer will be too.

- 32,821
- 6
- 50
- 72
-
Daniel, thx for the response. So it it ok to have persistance methods in a domain model, as long as the method just delegates to something like a mapper? I get confused when technically saving data is part of the business logic, but the methodology of the save process is part of application logic. – blacktie24 Apr 11 '11 at 15:36
-
@blacktie24, the basic idea is that the Model classes are supposed to be reusable across different applications. Ask yourself, if you wrote an application that handled input and output a different way but used the same model classes, would the logic you are concerned about also have to be put in a controller of the new app? If so, then the logic should probably be in the model itself. Hope this helps. – Daniel T. Apr 11 '11 at 21:11
-
Daniel, I really appreciate your input on this. With your example of having a new app with the same model classes, does this mean that generally speaking, the controllers should be very skinny, and other than getting some objects, invoking some methods, and mapping the proper view, most of the rest should be in the model? Also, as a side note, if I was using a datamapper, wouldn't all of that code be in the controller, and thus repeated across applications, unless i used active record? – blacktie24 Apr 12 '11 at 01:31
-
1@blacktie24, This doesn't mean that controllers should be very skinny. All it means is that the logic in them should be related to this particular application's UI, not the general problem space. Again, depending on what the environment means by MVC, the controller either interprets mouse moves and button taps, or it may start at a higher level, but its job is convert user input into changes in the model and sometimes the view as well. Controller's generally have to handle bad user input in an application specific way, and that isn't always a simple job. – Daniel T. Apr 12 '11 at 11:38
-
1@blacktie24, I just reread your comments. I see now that you are more focused in persistence whereas I have been focusing on user input. Yes your persistence system is not something that would be changed just because you are looking at/manipulating the model in a different way, so it is part of the model. However, it should be a plug-in replaceable component of the model so that it can change independently of other requirements. – Daniel T. Apr 12 '11 at 12:01
Data access (e.g. Database calls) should be in the Model.
User input should be handled by the Controller (where it may be handed off to a Model).

- 479,566
- 201
- 878
- 984
-
Hey Alex, thx for the reply. Doesn't having data access in the model couple the model to the db? – blacktie24 Apr 11 '11 at 15:40
-
@blacktie You need to have database interaction somewhere, and the model is the best fit place. – alex Apr 11 '11 at 23:21
-
Doesn't that make the model an active record? So in cases where you're using a data mapper, wouldn't the database interaction be happening in the controller? I posted this question today as well: http://stackoverflow.com/questions/5624319/why-does-active-record-pattern-not-work-with-rich-domain-models. Again, I really appreciate your input, Alex. – blacktie24 Apr 12 '11 at 01:09
-
-
Alex, can you explain that answer a little bit more, I didnt understand what you meant. – blacktie24 Apr 12 '11 at 01:39
This is good post on model-controller thing
as for ZF mvc implementation i think best approach is to keep almost everything in you model rather than controller. Controller is just for mapping user input to appropriate model methods.
My current model have several layers: static service locator, services(kinda business logic layer), models, and mappers.
Though my current implementation is bad in terms of OOP so i won't give you more details.
And quick example action from my app, simple catalog module:
public function addAction()
{
$service = Xrks_Service::getInstance()->getService('catalog', true);
if(!$service->checkAcl('addItem')) {
throw new Exception('You have no rights to view this page', 403);
}
$item = $service->getNewItem();
$form = $service->getEditForm($item); //here form created and filled with default values from model
if ($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost())) {
$service->populateModel($item, $form); //form->model mapper hidden behind service interface
$item->save();
$this->_helper->getHelper('Redirector')->gotoRouteAndExit(array('action' => 'edit', 'id' => $item->getId()), 'catalog-item');
}
$this->view->form = $form;
}

- 2,695
- 1
- 19
- 32
-
Xekrus, thx for posting. can you explain/show a little more your services layer? It looks like your services layer handles most of the heavy lifting. Is the mapper located in your services layer, or within your model? Why is your current implementation bad in terms of OOP? – blacktie24 Apr 11 '11 at 15:32
-
@blacktie24 it have too many interconnections, misplaced methods and so on. "Have no time to do correct OOP stuff right now, will fix it later" Well, it never was fixed. – Xerkus Apr 17 '11 at 18:42
-
Oh god, i would have killed whoever wrote this horrible code in this answer. – Xerkus Jun 30 '15 at 09:12