We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    Here’s another architectural type question... I’m building a module that’s using the Factory pattern (thanks to Shaun’s suggestions)... it dynamically loads other classes as needed.

    I have a bit of a mess right now because some of my classes get a reference to the parent object and some do not:
    class Child {
      var $ParentObject;
      __construct(ParentObject &$ParentObject) { 
         $this->ParentObject =& $ParentObject;
      }
    
    }
    // vs. a vanilla class:
    class StandAlone {
     __construct() { }
    }
    


    What that means is that my code that loads the new classes has to be configured as to what type of file it is loading (e.g. class name, whether or not it gets a reference of the parent, etc.).

    Am I missing the point of the Factory Pattern? Or should I just suck it up that my loader has to be able to deal with different types of classes? Originally, I had refrained from passing in the ParentObject reference because some of the classes simply don’t need that reference... they’re fine on their own.

    Thoughts? Am I just blowing my own mind?
      • 28215
      • 4,149 Posts
      Maybe something like this example will help:

      <?php
      /**
       * Factory examples
       */
      
      class Factory {
          public function newObject($class,array $config = array()) {
              if (class_exists($class)) {
                  $this->$class = new $class($this,$config);
              }
              return $this->$class;
          }
      }
      
      abstract class LoadableObject {
          public $factory = null;
      
          function __construct(Factory &$factory,array $config = array()) {
              $this->factory =& $factory;
              $this->config = $config;
          }
      
          public function getOption($key,$default = null) {
              if (isset($this->config[$key])) {
                  return $this->config[$key];
              } else if (!empty($default)) {
                  return $default;
              }
              return null;
          }
      
          abstract public function speak();
      }
      
      
      class Dog extends LoadableObject {
          public function speak() {
              return 'Woof!';
          }
      }
      
      class Cat extends LoadableObject {
          const OPT_CLAWS = 'claws';
      
          public function speak() {
              $claws = $this->getOption(Cat::OPT_CLAWS,2);
              return 'Meow!'.(!empty($claws) ? 'I have '.$claws.' claws!' : '');
          }
      }
      
      /* load our factory */
      $factory = new Factory();
      
      /* create a Dog object */
      $dog = $factory->newObject('Dog');
      echo $dog->speak(); /* prints "Woof!" */
      
      /* create some Cats */
      $cat = $factory->newObject('Cat');
      echo $cat->speak(); /* prints "Meow! I have 2 claws!" */
      
      $bigCat = $factory->newObject('Cat',array(
          Cat::OPT_CLAWS => 4,
      ));
      echo $bigCat->speak(); /* prints "Meow! I have 4 claws!" */
      
      
        shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com