Design Pattern: Factory Pattern in PHP

Factory pattern helps to separate the creator of the objects from the object classes. The creator/factory is responsible for generating objects.

Factory implementation process is not strict or predefined. The implementation depends on how we want to identify different objects and generate those.

In this article we are demonstrating the Factory pattern implementation in PHP programming language. Check the implementation details and examples below.

Implementation

Use the following steps to implement the Factory pattern in PHP-

  • Create item interface. This interface will be the base interface for all the item/product classes.
  • Create item/product classes and implement the interface.
  • Create factory class.
  • In factory class create a method to generate item/product classes. Accept some parameter to identify which object we want to generate, this identifier can be a string, integer, or any other type according to the preference.
  • Based on the provided identifier generate a new object of the desired class and return that object.

Here is a simple example of Factory pattern implementation in PHP-

<?php
// Factory pattern implementation on PHP

// Item/Product base interface
interface BaseItem {
    function operation1(): void;
    function operation2(): void;
}

// item class
class Item1 implements BaseItem {
    public function operation1(): void {
        echo "Item 1: operation 1\n";
    }

    public function operation2(): void {
        echo "Item 1: operation 2\n";
    }
}

// Define another item class
class Item2 implements BaseItem {
    public function operation1(): void {
        echo "Item 2: operation 1\n";
    }

    public function operation2(): void {
        echo "Item 2: operation 2\n";
    }
}

// Factory
class Factory {

    // Make this method static if you prefer
    public function getItem(int $type): ?BaseItem {
        // Generate object based on the parameter passed
        // If $type is 1 then return Item1
        // If $type is 2 then return Item2
        switch ($type) {
            case 1: return new Item1();
            case 2: return new Item2();
            default: return null;
        }
    }
}


// --- Demo ---
$myFactory = new Factory();

$item1 = $myFactory->getItem(1);
$item1->operation1();
$item1->operation2();

$item2 = $myFactory->getItem(2);
$item2->operation1();
$item2->operation2();

Output of the above code will be as below

Item 1: operation 1
Item 1: operation 2

Item 2: operation 1
Item 2: operation 2

Examples

Let’s take a look at a few examples of Factory pattern implementation in PHP.

Example #1: Transport

Here is an example of a simple Factory pattern implementation.

We are implementing a few item classes which represent different transports, and then we have a factory class for generating objects of those item classes.

Transport Interface

  • Create file “Transport.php”.
  • Define an interface “Transport”.
  • Declare methods as per requirement. Here we have methods – “start”, “stop”, “repair”.
<?php
// Transport.php

namespace BigBoxCode\DesignPattern\Factory\Transport;

interface Transport {
    function start();
    function stop();
    function repair();
}

Bike Class [Item Class]

  • Create file “Bike.php”.
  • Create class “Bike”.
  • Implement interface “Transport” for the class.
<?php
// Bike.php

namespace BigBoxCode\DesignPattern\Factory\Transport;

class Bike implements Transport {
    public function start() {
        echo "Bike started\n";
    }

    public function stop() {
        echo "Bike Stopped\n";
    }

    public function repair() {
        echo "Bike Repair\n";
    }
}

Car Class [Item Class]

  • Create file “Car.php”.
  • Create class “Car” and implement “Transport” interface.
<?php
// Car.php

namespace BigBoxCode\DesignPattern\Factory\Transport;

use BigBoxCode\DesignPattern\Factory\Transport\Transport;

class Car implements Transport {
    public function start() {
        echo "Car started\n";
    }

    public function stop() {
        echo "Car Stopped\n";
    }
    
    public function repair() {
        echo "Car Repair\n";
    }
}

Plane Class [Item Class]

  • Create file “Plane.php”.
  • Create class “Plane” and implement “Transport” interface.
<?php
// Plane.php

namespace BigBoxCode\DesignPattern\Factory\Transport;

class Plane implements Transport {
    public function start() {
        echo "Plane started\n";
    }

    public function stop() {
        echo "Plane Stopped\n";
    }

    public function repair() {
        echo "Plane Repair\n";
    }
}

Transport Factory Class

  • Create factory file named “TransportFactory.php”.
  • Create class “TransportFactory”.
  • Define method named “getTransport” which accepts a string param. and based on the param it generates an object of Bike/Car/Plane. And finally returns the object.

You can make the getTransport function static, if you prefer.

<?php
// TransportFactory.php

namespace BigBoxCode\DesignPattern\Factory\Transport;

class TransportFactory {

    public static function getTransport(string $type): ?Transport {
        switch (strtolower($type)) {
            case "bike":
                return new Bike();
            case "car":
                return new Car();
            case "plane":
                return new Plane();
        }

        return null;
    }
}

Demo

To use the implementation, create an object of “TransportFactory” first. Then use the object to generate object for bike/car/plane.

Then we can use the generated bike/car/plane object according to our need.

<?php
// demo.php

require __DIR__ . '/../../vendor/autoload.php';

use BigBoxCode\DesignPattern\Factory\Transport\TransportFactory;


$transportFactory = new TransportFactory();

$transport1 = $transportFactory->getTransport("bike");
$transport1?->start();

$transport2 = $transportFactory->getTransport("car");
$transport2?->start();

$transport3 = $transportFactory->getTransport("plane");
$transport3->start();

Output

We will get the following output if the above demo code is executed.

Bike started
Car started
Plane started

Example #2: Transport [Factory Method]

Let’s check a different implementation of factory than a simple factory.

We are implementing a factory method for generating transport objects.

Transport Interface

  • Create file “Transport.php”.
  • Define interface named “Transport”.
  • Declare some methods as per requirement.
<?php
// Transport.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

interface Transport {
    function start();
    function stop();
    function repair();
}

Bus Class [Road Transport – Concrete Item Class]

  • Create file “Bus.php”.
  • Create class “Bus” and implement interface “Transport”.
<?php
// Bus.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class Bus implements Transport {
    public function start() {
        echo "Bus started\n";
    }

    public function stop() {
        echo "Bus Stopped\n";
    }

    public function repair() {
        echo "Bus Repair\n";
    }
}

Bike Class [Road Transport – Concrete Item Class]

  • Create file “Bike.php”.
  • Create class “Bike” and implement the “Transport” interface.
<?php
// Bike.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class Bike implements Transport {
    public function start() {
        echo "Bike started\n";
    }

    public function stop() {
        echo "Bike Stopped\n";
    }

    public function repair() {
        echo "Bike Repair\n";
    }
}

Car Class [Road Transport – Concrete Item Class]

  • Create file “Car.php”.
  • Create class “Car” and implement the “Transport” interface.
<?php
// Car.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class Car implements Transport {
    public function start() {
        echo "Car started\n";
    }

    public function stop() {
        echo "Car Stopped\n";
    }

    public function repair() {
        echo "Car Repair\n";
    }
}

Plane Class [Air Transport – Concrete Item Class]

  • Create file “Plane.php”.
  • Create class “Plane” and implement the “Transport” interface.
<?php
// Plane.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class Plane implements Transport {
    public function start() {
        echo "Plane started\n";
    }

    public function stop() {
        echo "Plane Stopped\n";
    }

    public function repair() {
        echo "Plane Repair\n";
    }
}

Helicopter Class [Air Transport – Concrete Item Class]

  • Create file “Helicopter.php”.
  • Create class “Helicopter” and implement the “Transport” interface.
<?php
// Helicopter.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class Helicopter implements Transport {
    public function start() {
        echo "Helicopter started\n";
    }

    public function stop() {
        echo "Helicopter Stopped\n";
    }

    public function repair() {
        echo "Helicopter Repair\n";
    }
}

Transport Factory [Abstract Class]

  • Create a file named “TransportFactory.php”.
  • Create abstract class “TransportFactory”..
  • Declare an abstract method named “getTransport” that returns a Transport object.
  • Define method “operateTransport” and “repairTransport”. Use the “getTransport” method to generate a transport object and use that in the functions implementations. 
<?php
// TransportFactory.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

abstract class TransportFactory {
    public function operateTransport(string $name) {
        $transport = $this->getTransport($name);

        $transport->start();
        $transport->stop();
    }

    public function repairTransport(string $name) {
        $transport = $this->getTransport($name);

        $transport->repair();
    }

    public abstract function getTransport(string $name): ?Transport;
}

Road Transport Factory

  • Create a file “RoadTransportFactory.php”.
  • Create a class “RoadTransportFactory”.
  • Extend “TransportFactory” for this class.
  • Define abstract method “getTransport”. In the implementation generate object of Car/Bike/Bus and return that.
<?php
// RoadTransportFactory.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class RoadTransportFactory extends TransportFactory {
    public function getTransport(string $name): ?Transport {
        switch (strtolower($name)) {
            case "car":
                return new Car();
            case "bike":
                return new Bike();
            case "bus":
                return new Bus();
        }

        return null;
    }
}

Air Transport Factory

  • Create a file “AirTransportFactory.php”.
  • Create a class “AirTransportFactory”.
  • Extend “TransportFactory” for this class.
  • Define abstract method “getTransport”. In the implementation generate then object of Plane/Helicopter and return that.
<?php
// AirTransportFactory.php

namespace BigBoxCode\DesignPattern\Factory\TransportMethod;

class AirTransportFactory extends TransportFactory {
    public function getTransport(string $name): ?Transport {
        switch (strtolower($name)) {
            case "plane":
                return new Plane();
            case "helicopter":
                return new Helicopter();
        }

        return null;
    }
}

Demo

To use the implementation generate an object of the RoadTransportFactory or AirTransportFactory first.

Then we can use the factory and call the methods. We need to pass the identifier(string “bus”, “helicopter” etc.) for the object that we want to use.

<?php
// demo.php

require __DIR__ . '/../../vendor/autoload.php';

use BigBoxCode\DesignPattern\Factory\TransportMethod\AirTransportFactory;
use BigBoxCode\DesignPattern\Factory\TransportMethod\RoadTransportFactory;

$roadTransportFactory = new RoadTransportFactory();
$airTransportFactory = new AirTransportFactory();

$roadTransportFactory->operateTransport("bus");

$airTransportFactory->operateTransport("helicopter");

$roadTransportFactory->repairTransport("bike");

Output

Output will be as below.

Bus started
Bus Stopped

Helicopter started
Helicopter Stopped

Bike Repair

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check Factory pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.