Search code examples
phpobjectfactoryfactory-pattern

Using factory pattern in php to build car objects


I am looking for some help with this, I have written a factory pattern that does almost what I need, accept it will return me a new class based on the parameters.

What I need is a factory pattern that takes in some stuff and returns me an object of type car. This car will contain information such as Type, Model, year, Make and Odometer reading.

This is what I ave so far:

<?php
class Car_Factory_Pattern{

    protected $_instance;

    protected $_dependencies;

    public function getInstance(){
        if(null == self::$_instance){
            self::$_instance == new self();
        }

        return self::$_instance;
    }

    public function create($class){
        if(empty($class)){
            throw new Exception('Cannot declare and empty class.');
        }

        if(!isset(self::$_dependencies)){
            throw new Exception('The $dependencies are not set for this class');
        }

        if(!isset(self::$_dependencies[$class])){
            throw new Exception('This class does not exist in the dependencies array');
        }

        if(isset(self::$_dependencies[$class]['params'])){
            $new_class =  new $class(implode(', ', self::$_dependencies[$class]['params']));
            return $new_class;
        }else{
            $new_class = new $class();
            return $new_class;
        }       
    }

    public function registerDependencies(array $array){
        self::$_dependencies = $array;
    }
}

The data structure you would need for this is:

function dependencies(){

$dependencies = array(
    'Car_Class' => array(
        'params' => array(
            'Type',
                            'Model',
                            ...
        ),
    ),          
);

return $dependencies;

}

You then instantaite the class by doing:

$factory = Car_Factory_Pattern()::getInstance();
$factory->registerDependencies(dependencies());

which then lets me do:

$some_car = Car_Factory_Pattern()::create('Car_Class');

The problem with this is that I have essentially hard coded the dependencies, which works for another application I am working on, how ever - What I need this class to do is take in the type, model, make, year and odom reading and give me back an object of type car, regardless of what you pass in, I could create a class that takes an array of options how ever I was hoping the factory pattern would do that for me - unless I am mistaken?

Thanks for the help.


Solution

  • Tht's my idea of factory. The class keep a singleton of every new class, and all the car classes extend a base car_class that give you the ability to set the depencies. This approach save the resources to create a new car object every time Thanks to @NiclasLarsson for the magic get

    <?php
    class Car_Factory_Pattern{
    
        protected $_instance;
    
        public static function getInstance($class){
            if(null == self::$_instance){
                self::$_instance[$class] = new $class();
            }
            return self::$_instance[$class];
    
        }
    }
    
    class Base_Car {
     private $aVariables = array();
    
     public function __construct( ) {
       // to oveload
     }
     public function populate( $aData = array() ) {
      $this->aVariables = $aData;
     }
    
     public function __get( $sKey ) {
      return isset($this->aVariables[$sKey]) ? $this->aVariables[$sKey] : NULL;
     }
    }
    
    
    class Example_Car extend Base_Car {
    
     public function __construct( ) {
       // do heavy initialization
     }
    
      // other functions
    
    }
    
    $car = Car_Factory_Pattern::getInstance('Example_class');
    $car->populate(depencies());
    

    ADD

    Using the @NiclasLarsson Example_Car class

    class Forge_Car{
    
      public static function create($class,$depencies){
        return new $class($depencies);
      }
    }
    
    
    $car = Forge_Car::create('Example_Car', depencies());