Page 1 of 1

How should I refactor switch to front controller design?

Posted: Sun Mar 18, 2007 11:29 pm
by alex.barylski
Refactoring a rather large switch statement like application...

Inside the index.php before the first switch, I have initialize the master template.

Each switch CASE looks something:

Code: Select all

switch($page){
  case 'homepage':
    break
  case 'addresses':
    break;
  case 'statistics':
    break;
  case 'admin':
    break;
}
Each of those switch statement might have an arbitrary level of nested switch statements which basically further refine the handling behevior or GUI based on levels and templates, included, etc...

Still with me? Good :)

Like I said originally, the master template is initialized before the first switch because it's the common peice throughout the applicaiton - makes sense.

Where would I refactor this code to? Should it stay in the index.php or move into a master controller class? Should I use a intercepting filter?

Considering the arbitrarty levels of nesting, how would this best be broken up to be mroe MVC friendly? Using a front controller (model 2) design.

I envision the index.php to basically:
- Include required includes
- Authentication
- Application wide initialization

Here is another caveat: What do I do with scripts whose sole purpose was to execute some action (create a user) and redirect back? How does that fit into the MVC/Front Controller design?

Should I have two first line controllers:
- Master controller (initializes master template, etc)
- Action controller (carry out actions *only*) and continue to success messages or original screen, etc

The action controller could potentially grow to ugly girth by using this approach, I could probably break it up like the template controller, in that the first line controller would handle CRUD operations and each CRUD function would further delegate to another specialized controller and so on...this is something like the technique I want to use with the template controller as well.

Cheers :)

Posted: Mon Mar 19, 2007 7:59 am
by Jenk
Transpose those major actions into sub-controller objects, then any page/actions specific sub-actions into methods, ala what Zend does.

Posted: Mon Mar 19, 2007 11:40 am
by alex.barylski
Not sure I understand..but if I do, I don't think that would work because the navigation looks like:

Code: Select all

level 1:1
level 1:2
 level 2:1
 level 2:2
 level 2:3
  level 3:1
  level 3:2
   level 4:1
And so on...the nesting levels are arbitrary so inheritence or relying on the controller then methods would only provide 2 levels of nesting...unless i misunderstand...

Cheers :)

Posted: Mon Mar 19, 2007 11:46 am
by Kieran Huggins
I separate templating scenarios by subdomain ( domain.com / ajax.domain.com / json.domain.com / m.domain.com... etc...)

It seems to me that a script with no desired output could just use a header();die() to redirect (and skip the templating).

I agree with Jenk in that you should create a controller for each action, and a method for each sub-action.

I use a series of regular expressions as a router - each trying to match in order, then finally defaulting to a catch-all solution if there's no match. You might find that handy in your situation?

Posted: Mon Mar 19, 2007 2:51 pm
by alex.barylski
I'm not were understanding each other :P

The obvious solution is to break each logical page into a controller and it's actions as the controller methods...but as it stands right now I'm not sure if thats ideal...

Hanlding AJAX does, sometime require me to instantiate the template engine, but not the master, only that portion of the page which is refreshed - which complicates things :)

The issue I am facing, I believe has to do with page "state"

With an arbitrary depth level of pages and sub-pages, it almost makes sense to keep it as a switch statement with embedded switch statement further refining the page request/repsonse delivery...

What is making it even more complicated to explain is that I don't clearly understand what the problem is myself...

Posted: Mon Mar 19, 2007 3:54 pm
by John Cartwright
I'm not sure exactly why you are so fixed on using nested switch statements in the first place. Could you shed some light on exactly what you doing with all these sub pages? Even still, there is nothing wrong with using subcontrollers.

All this nesting suggests to me that you could furthur seperate the logic in your code, and possibly in the file structure as well.. So for instance, instead of having nested actions in your "admin" controller, you could seperate this monolithic switch into several smaller independent components.

As for AJAX, and using the controller/action technique doesn't really play any different.. You can pretty much treat the requests the same.

Posted: Mon Mar 19, 2007 4:12 pm
by alex.barylski
I'm not fixed on using nested switch, it's how it's already built and I am trying to modularize using front controller and page controllers.

It looks something like:

Code: Select all

$tab1 = $_GET['tab1'];
$tab2 = $_GET['tab2'];

$page = $_GET['page'];

switch($tab1){
  case 'dashboard':
    break;
  case 'articles':
    switch($tab2){
      case 'manage':
        switch($page){
          case 'browse':
            break;
          case 'create':
            break;
          case 'update':
            break;
        }
        break;
      case 'search':
        break;
    }
    break;
}
As you can see from the above, arbitrarty levels is quite possible as each level refines itself, so although 2 or 3 is typical, it should not be limited to any specific level of nesting...

Make sense? :)

It's a complicated application, which requires state preservation (indicated by tabs being selected or not) bring up one tab it displays others in it's body and clicking on those sub tabs will potentially bring up other sub-pages, etc and so on...

After hours of study and consideration I think I finally figure out how to best organize everything, but as always I'm interested in hearing others options or experiences... :)

As it stands I have a master controller which delegates to sub-controllers which can delegate to other sub-controllers, etc...tying in the views is what i'm working on as we speak...as well as figuring how to organize the index.php to handle view requests, AJAX (which is both view and action) and action events. :)

Cheers :)

Posted: Mon Mar 19, 2007 4:12 pm
by Maugrim_The_Reaper
Nesting should be irrelevant to a controller scheme - you should be able to compose a url pointing to any specific View, and therefore any selection of logic underpinning such a view (since a View would be referenced by the controller). I get the feeling you need to understand the problem before you understand the answers you'll get :).
With an arbitrary depth level of pages and sub-pages, it almost makes sense to keep it as a switch statement with embedded switch statement further refining the page request/repsonse delivery...
Doesn't make sense - resources on the web only have two hierarchies: directory structure and resource collation. In a View, you could have a dozen sub-Views feeding it. But the sub-Views have no knowledge of a parent, and therefore don't have a hierarchy position. You can request them in isolation without depending on a parent View's details. So either a) you're complicated a simple idea, or b) you're allowing a requirement to complicate the idea in the wrong way.

AJAX isn't a complex animal - yes, it's more refined than a big page. But sub-Templating has been in applications on the server side for years. I can't think of a good reason why it needs nesting or a hierarchy to function - you could stick everything in the same directory or URI domain and it should work perfectly well. The only nesting of pages detail worth using is as a "location" for users in a web-app since user's are of course more interested in specific locations, categories, subsections etc. The application shouldn't give a toss.

Posted: Mon Mar 19, 2007 4:19 pm
by alex.barylski
I'm *not* really geared towards a nested switch like demonstarted above :P

I'm am trying to convert to front controller...

I think if you could take my above example using a psudeo front controller API (not zend) and show how my situation could be converted into a modular codebase, that would help :)

I'm not arguing against front controller design, but I'm struggling with the best way to solve the problem using a front controller...

Do controllers derive from other controllers or is their heirarchy expressed implicitly through the front controller system via the call chain...

Posted: Mon Mar 19, 2007 7:25 pm
by John Cartwright

Code: Select all

switch($tab1){
  case 'dashboard':
    break;
  case 'articles':
    switch($tab2){
      case 'manage':
        switch($page){
          case 'browse':
            break;
          case 'create':
            break;
          case 'update':
            break;
        }
        break;
      case 'search':
        break;
    }
    break;
}
would loosely translate into something similar to

Code: Select all

class Dashboard extends foobar_Framework_Controller
{
	public function IndexAction()
	{
		
	}
}

class ArticleManager extends Foobar_Framework_Controller
{
	public function BrowseAction()
	{

	}
	
	public function CreateAction()
	{
	
	}
}

class ArticleSearcher extends Foobar_Framework_Controller
{
	public function SearchAction()
	{
	
	}
}
Wish I had more time to address your thread, but I only have a moment.

Posted: Tue Mar 20, 2007 3:15 am
by alex.barylski
Hmmm....thats cool...

It's essentially what I have right now...but something doesn't feel right...not sure why...in anycase...I'll just bring up my issues here if I have any more questions :)

Cheers :)