Search code examples
phpoopdependency-injectionfactory-pattern

How to apply factory pattern php


I'm not sure how do factory pattern is applied.

If I take this code as example:

class Car
{
    protected $_engine;
    protected $_frame;
    protected $_wheels;

    public function __construct($engine,$frame,$wheels)
    {
        $this->_engine = $engine;
        $this->_frame = $frame;
        $this->_wheels = $wheels;
    }
}

class Engine
{
    protected $_hp;

    public function __construct($hp)
    {
        $this->_hp = $hp;
    }
}

class Frame
{
    protected $_type;
    protected $_length;

    public function __construct($type,$length)
    {
        $this->_type = $type;
        $this->_length = $length;
    }
}

class Wheels
{
    protected $_diameter;

    public function __construct($diameter)
    {
        $this->_diameter = $diameter;
    }
}

class CarFactory
{
    // ???
}

How is the factory supposed to create all the parts of the car? Do I need a factory for every part? If so, how does the CarFactory know about them? The combination of IOC, DI and factory pattern confuse me where everything or anything should be initiated. I see the benefits of them all (I think).

How does Dependency Injection come into play here? Every part could have been its own object but for simplicity I left it out for now.

Hopefully my question is clear enough.

Thanks in advance!


Solution

  • You need to use factory if you have different types of cars.

    class Car
    {
        protected $type;
    
        public function drive()
        {
            echo 'Zoom-zoom!';
        }
    
        public static function factory($driven)
        {
            $instance = null;
            switch ($driven) {
                case 2:
                    $instance = new Sedan;
                    break;
                case 4:
                    $instance = new Crossover;
                    break;
                default:
                    throw new Exception('Invalid driven type: ' . $driven);
            }
    
            return $instance;
        }
    }
    
    class Sedan extends Car
    {
        // some things for sedan
    }
    
    class Crossover extends Car
    {
        // some things for Crossover
    }
    
    $sedan = Car::factory(2);
    $crossover = Car::factory(4);
    
    $sedan->drive();
    $crossover->drive();
    

    Something like that.