Page 1 of 1
Writing a controller.. where to put code that does stuff?
Posted: Thu May 03, 2007 5:22 pm
by onion2k
I'm writing a front controller / MVC type of system for a new site. At the moment I have a system that loads an different object depending on what the user is viewing..
Code: Select all
switch ($section)
{
case "admin": $viewClass = "ViewAdmin"; break;
case "article": $viewClass = "ViewArticle"; break;
case "archive": $viewClass = "ViewArchive"; break;
case "labels": $viewClass = "ViewLabel"; break;
case "about": $viewClass = "ViewAbout"; break;
default: $viewClass = "ViewIndex"; break;
}
if (file_exists(PATH."content/view/".$viewClass.".inc.php"))
{
include_once(PATH."content/view/".$viewClass.".inc.php");
} else {
$viewClass = "ViewError";
include_once(PATH."content/view/".$viewClass.".inc.php");
}
// -----------------------------------------------------------------------------
// View
$view = new $viewClass($databaseLink);
$view->drawHeader();
$view->drawBody();
$view->drawContent();
$view->drawFooter();
The viewing of pages is fine, no problem. The problem is where to put code to do things like adding comments, adding labels, editing pages and so forth. The easiest approach is to put it into the view object code but that doesn't really fit with the MVC approach. It doesn't seem to make much sense to create a whole new set of objects for interacting with each section either though. All the tutorials and articles I've read about MVC seem to stop once the view code is done ... there's nothing about how forms are handled. Where does this code normally go?
NOTE: This has to be done in PHP4.
Posted: Thu May 03, 2007 8:18 pm
by Nathaniel
It seems like you have a controller and a view, but no model. So I guess you'd copy and paste your code:
Code: Select all
switch ($section)
{
case "admin": $modelClass = "AdminModel"; break;
case "article": $modelClass = "ArticleModel"; break;
// and so on...
}
if (file_exists(PATH."content/model/".$modelClass.".inc.php"))
{
include_once(PATH."content/model/".$modelClass.".inc.php");
} else {
// you get the idea
}
$view = new $viewClass( new $modelClass($databaseLink));
I'm no OOP expert, so someone correct me if I don't have the basic idea down.
Posted: Thu May 03, 2007 8:29 pm
by John Cartwright
Code: Select all
$model = new $modelClass($databaseLink);
$view = new $viewClass();
$view->drawComments($model->getComments());
The view technically has no business dealing with the model itself, it is the controllers duty to control the flow. Usually you would only pass the data to the view to be outputted.
Posted: Thu May 03, 2007 8:44 pm
by Nathaniel
Oh well, that makes sense. Thanks Jcart.
Re: Writing a controller.. where to put code that does stuff
Posted: Thu May 03, 2007 11:30 pm
by Christopher
onion2k wrote:I'm writing a front controller / MVC type of system for a new site. At the moment I have a system that loads an different object depending on what the user is viewing... All the tutorials and articles I've read about MVC seem to stop once the view code is done ... there's nothing about how forms are handled. Where does this code normally go?
You know the saying about the hardest step in a journey is the first one -- well it's true about most things, but not controller architectures.

You are on the first couple of steps and every step forward from here is hard.
You appear to have a Page or Action Controller that internally selects the View -- which is sort of like an Action. But you are not using Dispatch or the Command pattern or a Front Controller or all the other stuff that you end up with when you dive into the deep-end of the MVC pool ...
I guess the core question is about whether you can go the intuitive short-cut route of not creating "a whole new set of objects for interacting with each section." The short answer is
no. The thing about MVC is that it requires you to do a little more work always, but you get the benefit that as application complexity increases the amount of additional work you need to do does not increase nearly as fast as going the short-cut route.
Posted: Fri May 04, 2007 3:01 am
by Maugrim_The_Reaper
Jcart wrote:The view technically has no business dealing with the model itself, it is the controllers duty to control the flow. Usually you would only pass the data to the view to be outputted.
Not true

. In MVC the View is allowed to make requests for data from the Model. The only difference on this point between the Controller and View is that the Controller can read and write to/from the Model while the View's dealings must be read-only. This maintains the separation of each layer since only the Controller can alter the Model. I've been arguing this point a lot recently. View/Model interaction is described in a few places. If you read the summary explanation of Template View in POEAA online it makes the connection obvious showing a template using a "BookHelper" class to grab data from a Model. Nary a sign of a Controller class...
http://www.martinfowler.com/eaaCatalog/ ... eView.html
onion2k wrote:I'm writing a front controller / MVC type of system for a new site.
Writing MVC from scratch is never going to be easy. Depending on your needs my first recommendation would be to evaluate a framework so you don't need to do all the inevitable up front work yourself. The more complex the website and application, the more time your own initial groundwork will take.
Arborint and I have spent a bit of time discussing page generation in an MVC setting (we are starting from the Zend Framework and it's View layer is not so complicated that the discussion might illustrate a few ideas for you). The trick is in putting each separable "part" of a web page into it's own template. By itself that enables re-use in any other part of the application. The second step is adding a Composite layer for combining these separated templates at runtime into whatever specific overall View you want according to some "layout".
In the discussion I started on some code for allowing templates control layout using internal "include" type methods. Probably because I'm poisoned by reading too many JSPs

. There are alternate methods and arborint is working on one of them I think. His might be closer to what you need given your use of View classes in assembling pages.
Posted: Fri May 04, 2007 7:08 am
by kyberfabrikken
The controller in a web application, is the "prime mover". It's where the request enters, and where you decide what to do. The controller can (optionally) update the model, and should then dispatch to a view. The view renders the output (response). It goes like this:
Code: Select all
(Request) => Controller => View => (Response)
If you use a front controller, then you add an additional layer to the controller. The front controller should be the single entrypoint for all requests, and it will then dispatch to a concrete handler (Often named Action, Command, or Controller). This handler will then do what controllers do (update a model, and dispatch to a view). So you get:
Code: Select all
(Request) => Front Controller => Controller => View => (Response)
In web applications, you often have controllers, which does nothing but dispatch. And more importantly, you often have controllers which always dispatch to the same view, thus forming a 1:1 relationship between controller and view. In these cases, the distinction between view and controller is rather abstract, and you may be just as well off combining the two into one entity. If you are a bit weary about where what goes, I suggest that you follow such a two-tier architecture. You can still combine this with a front controller. This gives you the following pipeline:
Code: Select all
(Request) => Front Controller => Handler => (Response)
All these examples have in common, that they deal with input/output of your application. The Model layer, sits on the side, and is accessible from each of these actors at any time. If you follow an MVC approach, the Controller is allowed to update the Model, while the View is only allowed to read from it.
Posted: Fri May 04, 2007 8:21 am
by onion2k
Cor.. lots of ideas. Cheers everyone, I think I'll be able to make some progress.
Posted: Fri May 04, 2007 10:02 am
by Christopher
Maugrim_The_Reaper wrote:The only difference on this point between the Controller and View is that the Controller can read and write to/from the Model while the View's dealings must be read-only. This maintains the separation of each layer since only the Controller can alter the Model.
This is not exactly true. The View and Controller are in the same layer -- the Presentation Layer. The Model is in the Domain layer. So the separation between M and VC is a layer one. Whereas the separation between V and C is only about separation of concerns. There is no strict rule as to how an application divides the concerns in the Presentation Layer between the View and Controller. The layer separation between the Model and Presentation is clearer -- though no completely strict - and pretty boring.
This is what makes designing Controllers and Views so interesting (and either fun or maddening depending on how you look at it).
Posted: Fri May 04, 2007 11:56 am
by John Cartwright
Fair enough, at least we agree views are only allowed to read data

Posted: Fri May 04, 2007 12:16 pm
by Christopher
Jcart wrote:Fair enough, at least we agree views are only allowed to read data

Yes.
But there is a "but" for all of these patterns. Even Fowler recognized cases where the Model needs to have a dependency on the View. And there are Views and then there are Views:
http://martinfowler.com/eaaDev/AutonomousView.html
http://martinfowler.com/eaaDev/PassiveScreen.html
And to confuse the issue further there are Controllers and then there are Presenters that mix in more View into the Controller. The bottom line is that knowledge is power when faced with making these design decisions.