Page 2 of 2

Posted: Fri Aug 03, 2007 5:56 pm
by Christopher
matthijs wrote:However, my main question now is how the actual processing by the controllers goes. A single controller/actions pair is clear. The Frontcontroller looks for a controller class in a specific directory, runs the given action or the default one.
Ok ... you are clear so far.
matthijs wrote:But with a deeper nested set you end up with controllers with massive deeply nested if/then/else loops. Which are basically a copy of the mapper scheme. This controller management. Is it something you solve up front (in the front controller or mapper) or for each controller separately? I hope I'm clear what I mean.
This is where I get confused. The idea with a Front Controller is that you build many atomic Action Controller that are focused on specific tasks. If you need additional functionality you either add more actions (action methods) or you add additional controllers and link redirect or forward to them. If you need specific hierarchical controller behavior then implement an base action controller class that looks at additional parameters and dispatched additional controllers.

On the View front, you can just attach strings or Template objects or View objects together to build any tree you want.

However usually straight "/controller/action/" is more than enough for most sites. Going back to one of your examples, "/users/germany/new/edit/" should probably be "/users/edit/new/country/germany/" where your route is "/controller/action/id/param1/value1/".

Posted: Sat Aug 04, 2007 1:13 am
by matthijs
arborint wrote:The idea with a Front Controller is that you build many atomic Action Controller that are focused on specific tasks.
Exactly. That's the reason I got a bad feeling about the way things were evolving in my code.
arborint wrote:If you need additional functionality you either add more actions (action methods) or you add additional controllers and link redirect or forward to them.
Ok, so thats:
1) more actions

Code: Select all

class module {
    // ...
    function action($locator){
        // some logic here

        // in some cases use another action
        $this->someotheraction();
    }
    function someotheraction(){}
    // ...
}
2) link

Code: Select all

class module {
    // ...
    function action($locator){
        // some logic here

        // in some cases instantiate another controller
        $action = new SomeController($locator);
        $result = $action->getContent();
    }

    // ...
}
3) redirect

Code: Select all

class module {
    // ...
    function action($locator){
        // some logic here

        // in some cases redirect
        $this->redirect($url);
    }
    // ...
}
3) forward

Code: Select all

class module {
    // ...
    function action($locator){
        // some logic here

        // in some cases forward
        $this->forward($url);
    }
    // ...
}
arborint wrote:If you need specific hierarchical controller behavior then implement an base action controller class that looks at additional parameters and dispatched additional controllers.
The thing in this whole discussion is that it's not even clear to me, but this suggestion of a base action controller might be worthwhile to look into. At the least it might prevent too much coupling and prevent too much duplication.
arborint wrote:However usually straight "/controller/action/" is more than enough for most sites.
I agree. But at the same time, I don't want to be restricted by that. My URLs should be as logical as possible.

Ok, lots to think about. Thanks for your input so far, very helpful!
(p.s. what do you guys do when you feel your head is about to explode from thinking too hard?)

Posted: Sat Aug 04, 2007 4:05 am
by s.dot
Hmm, reading this topic just made a few things finally click about object orientation inside my head. That's freakin' awesome. Or maybe it clicked about the controller in MVC. Not sure, but I'm going to have a few plays with some code now.

Posted: Sat Aug 04, 2007 1:45 pm
by Christopher
One of the goals of that code base is that it is simple enough to understand what is going on, yet powerful enough to build real websites. That was always the goal. Controllers can be difficult to understand and most frameworks have so many would-be-nice features that the code is difficult to follow.

Posted: Sat Aug 04, 2007 1:57 pm
by matthijs
Yes, that's true. I've studied the way ZF handles routing this afternoon and see how the added flexibility also adds a lot of complexity. Maybe I can find some middle ground, if needed, with some form of controller helper or actioncontroller (as you suggested).
scottayy wrote:Hmm, reading this topic just made a few things finally click about object orientation inside my head. That's freakin' awesome
I get your feeling. At first, it's very frustrating to understand how things work, because you (or at least I did) try to understand what's going on "behind the curtains", in the black box so to say. But then comes a point when you realize that the whole point of a bigger framework of object oriented code is not to try to understand what's going on in the black box. It's only important to understand the separate classes and how the interfaces work, and then start playing with the classes like they are blocks of Lego.

At least, that's my current feeling. Might change with the next revelation ;)

Posted: Mon Aug 06, 2007 12:35 am
by matthijs
Ok, some more study and things suddenly clicked :) (suddenly for me, some might call it finally)

I can see now that there are a couple of strategies of routing/mapping. All have their strengths and weaknesses. Often it's a trade off between simplicity and convention on one side and be-able-to-do-everything and complexity on the other side. Of course, it's not black and white, and in the middle ground there are some solutions which combine a lot of simplicity with a lot of flexibility.

Convention of dispatching/mapping to controller/action pairs
The current setup I have (skeleton code) has a simple convention of mapping to controller/action pairs. In the 80/20 rule, this is the 20% complexity which can do 80% of the work. If I need that other 20%, it'll probably take a lot more to get it done.

Dispatching based on more elaborate request/mapping configuration
This is what the ZF seems to do. You spend (a lot) more time up front setting up the different routes, including all options and restrictions. Haven't build something with the ZF yet, so don't know how it's after that.

Dispatching through a series of controllers
A kind of chain of controllers/commands. Each controllers checks if it is able to perform an action. If not, forward to next controller in the chain. This is what Konstrukt does.
Should be possible to use a composite pattern to keep individual controllers simple and pluggable.

At this point I probably will stick with the controller/action convention. For most of the situations (in my project) that will be enough. However, I don't want to sacrifice the setup of my URLs, so in cases I need the deeper nested controller structures I will just dispatch from the controller to child controllers manually. That will introduce a bit of duplication and coupling, but I might be able to get that out later. Maybe with a kind of action helper.

Any more thoughts? Did I miss some things?