[Refactored] Would you refactor this to involve a Factory?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

[Refactored] Would you refactor this to involve a Factory?

Post by nielsene »

Here's my evolving FrontDispatcher

Code: Select all

class FrontDispatcher {

  var $_mappings=array();
  function FrontDispatcher() {
    $this->_mappings["|register/[-A-Za-z0-9_]*/Admin|"]="SlidingDoorsAdmin";
  }
  
  function _findModule() {
    foreach($this->_mappings as $pattern=>$module)
      if (preg_match($pattern,$_SERVER["REQUEST_URI"]))
	return $module;
    return "";
  }

  function _createModuleController($className) {
    $className.="Controller";
    require_once("classes/controllers/$className.inc");
    $mc =& new $className();
    return $mc;
  }

  function _createModuleRequest($className) {
    $className.="Request";
    require_once("classes/requests/$className.inc");
    $req =& new $className();
    return $req;
  }

  function _createModuleContext($className) {
    $className.="Context";
    require_once("classes/contexts/$className.inc");
    $con =& new $className();
    return $con;
  }

  function dispatch() {
    $moduleName = $this->_findModule();
    if ($moduleName!="") {
      $req =& $this->_createModuleRequest($moduleName);
      $con =& $this->_createModuleContext($moduleName);
      $mc  =& $this->_createModuleController($moduleName);
      $mc->invoke($req,$con);
      return 1;
    }
    else return 0;
  }

}
?>
The simple Mapping array is about to be replaces -- > request templates need to map to a module name AND to a handler chain. The last handler in the chain will be the current ModuleController. (Ie I want to add a DBUnavailableHandler, BadCupHandler before the immediate dispatch to the module controller (which has its own set of mappings->CoRs)

However the collection of _createModuleFoo's is making me wonder if I should pull those three out to a Factory? They already are FactoryMethods.... would you make a Factory class for them to keep the dispatcher only worried about dispatching?
Last edited by nielsene on Thu Aug 25, 2005 11:14 pm, edited 1 time in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

a Factory class sounds like where to head. :)
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

Nice work nielsene! Thanks for the post. I'm learning a lot from your posts!
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

Post by nielsene »

Well I think I got the refactoring done, now to see if I can clean-up the mock-based tests.... grrr.... Once it all checks out, I'll post the new version....
User avatar
nielsene
DevNet Resident
Posts: 1834
Joined: Fri Aug 16, 2002 8:57 am
Location: Watertown, MA

[Refactored] Would you refactor this to involve a Factory?

Post by nielsene »

So here's the followup post with the refactored version:

First the new FrontDispatcher

Code: Select all

class FrontDispatcher {

  var $_mappings=array();
  function FrontDispatcher() {
    $this->_mappings["|register/[-A-Za-z0-9_]*/Admin|"]="SlidingDoorsAdmin";
  }
  
  function _findModule() {
    foreach($this->_mappings as $pattern=>$module)
      if (preg_match($pattern,$_SERVER["REQUEST_URI"]))
	{
	  $factory =& new ModuleFactory($module);
	  return $factory;
	}
    return NULL;
  }

  function dispatch() {
    $factory =& $this->_findModule();
    if ($factory!=NULL) {
      $req =& $factory->createRequest();
      $con =& $factory->createContext();
      $mc  =& $factory->createController();
      $mc->invoke($req,$con);
      return 1;
    }
    else return 0;
  }

}
Now the ModuleFactory

Code: Select all

class ModuleFactory {

  var $_moduleName;
  function ModuleFactory($moduleName) {
    $this->_moduleName=$moduleName;
  }

  function _create($type) {
    $className=$this->_moduleName.$type;
    $dirName=str_tolower($type)."s";
    require_once("classes/$dirName/$className.inc");
    $obj =& new $className();
  }


  function createController() {
    return $this->_create("Controller");
  }

  function createRequest() {
    return $this->_create("Request");
  }

  function createContext() {
    return $this->_create("Context");
  }

}
I'm a little surprised that it seems to run without notices... I thought that the assigning a reference with NULL would cause problems I guess I'm still on a "sane" version of php....
Post Reply