PHP Design Patterns - Factory

PHP
Aug 20, 2020
In this article we'll look at a simple PHP Factory Design Pattern. Factory pattern is perhaps the most common pattern used. Factory pattern is nothing more than what the name says. Its a factory example: car factory, pizza factory, ice cream factory, gadgets factory you name it.

What is a Factory

The definition of a factory can read something like this, it's the place where something is made or assembled. An example of a factory is a place where cars are built. A factory is defined as something that makes things quickly and in great quantities.

Factories in programming terms is mostly the same, its a place (class, method etc.) in our code base where an object is made or assembled. You can build multiple objects in a factory and assemble it together. Lets look at a simple example of an IceCreame factory.

Using Open–closed principle (SOLID), we always code to an interface rather than concrete implementation. This allows us to open up for extension but closed for modification. so lets start by creating an interface

        
interface IceCream
{

    public function withExtra($extra);

}
        
    

The IceCream interface will define a contract with one public method called withExtra($extra) that will accept exactly one parameter called extra. What the contract says is, no matter what when you implement me, you must implement the withExtra($extra) method and have some sort of logic implemented.

Lets take a look at how the IceCream class looks like.

        
class OreoIceCream implements IceCream
{

    protected $flavour;

  
    protected $extras = [];

    
    public function __construct($flavour)
    {

         $this->flavour = $flavour;

    }
  

    public function withExtra($extra): OreoIceCream
    {

         $this->extras[] = $extra;
      
         return $this; 

    }
  

    public function serve(): string
    {

        $extras = implode(", ", $this->extras) ?: 'None';

        echo "Enjoy your {$this->flavour} ice cream. Extras: {$extras}.";

    }

}
        
    

As you can see, the class implements the withExtra($extra) with exactly one parameter. In this case all we're doing is assigning the extra to an property on the class which is of type array. You can have any number of additional methods, properties as you like.

Ok, now that we have or contract defined and the IceCream class, lets move on to the factory. What we want now is some way of dynamically building an IceCream object for us based on the flavour lets say. We could have different flavoured Ice creams and depending on which one you ask for the factory will build and assemble it for us.

        
class IceCreamFactory
{

    public static function make($flavour): IceCream
    {

        $className = $flavour."IceCream";

        return new $className($flavour);

    }

}
        
    

Our simple Factory class has a make() method on it that will be responnsible to build the object for us. Lets see how we can use it now.


$icecream = IceCreamFactory::make('Oreo');

echo $icecream

  ->withExtra('Choco Chips')

  ->withExtra('Marshmallows')

  ->serve();


// Output: Enjoy your Oreo ice cream. Extras: Choco Chips, Marshmallows.

    

In the above example we're asking the Ice cream factory to make us an OreoIceCream. The factory in the case just builds us a simple class but this will be the place where you can build additional objects that the IceCream class might need and pass it to it.

Now that you have opened up for extension, its really easy to have the factory build a CookieAndCream Ice Cream, all you need to do is create a new CookieAndCream class that will implement the IceCream interface and that's it you're all good to go. The only thing to remember is to implement the withExtra($extra) method.

That's it you have your simple factory. Hope you find this article useful đź‘Ť.