Factory Design Patterns in PHP

Factory Design Patterns in PHP

PHP Factory Pattern Example

The Factory pattern helps you create one of a number of interchangeable patterns in a way that is easy to maintain and extend.

Factory Pattern: problem & solution

Problem

Solution

  • You want to create an instance of a class but you don’t know in advance the object class you need to use
  • You want to localize the knowledge of which class must be instantiated
  • The Factory Method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate.
  • The Factory Method defers instantiation

Factory Pattern: considerations

  • It’s difficult to find in PHP an original implementation of the Factory Method as defined by the GoF
  • There are different variation to the original Factory Method
  • The GoF discussed both Factory Method and Abstract Factory

The main goal of this pattern is to encapsulate the creational procedure that may span different classes into one single function. By providing the correct context to the factory method, it will be able to return the correct object.

The best time to use the factory method pattern is when you have multiple different variations of a single entity. Let’s say you have a button class; this class has different variations, such as ImageButton, InputButton and FlashButton. Depending on the place, you may need to create different buttons—this is where you can use a factory to create the buttons for you!
Let’s begin by creating our three classes:

<?php

abstract class Button {
	protected $_html;

	public function getHtml()
	{
		return $this->_html;
	}
}

class ImageButton extends Button {
	protected $_html = "..."; //This should be whatever HTML you want for your image-based button
}

class InputButton extends Button {
	protected $_html = "..."; //This should be whatever HTML you want for your normal button (<input type="button"... />);
}

class FlashButton extends Button {
	protected $_html = "..."; //This should be whatever HTML you want for your flash-based button
}
?>

Now, we can create our factory class:


<?php
class ButtonFactory
{
    public static function createButton($type)
    {
        $baseClass = 'Button';
        $targetClass = ucfirst($type).$baseClass;

        if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass)) {
            return new $targetClass;
		} else {
            throw new Exception("The button type '$type' is not recognized.");
		}
    }
}
?>

We can use this code like so:

<?php
$buttons = array('image','input','flash');
foreach($buttons as $b) {
    echo ButtonFactory::createButton($b)->getHtml();
}
?>

The output should be the HTML of all your button types. This way, you would be able to specify which button to create depending on the situation and reuse the condition as well.

Complete Example:

<?php
abstract class Button {
	protected $_html;
	public function getHtml()
	{
		return $this->_html;
	}
}
class ImageButton extends Button {
	protected $_html = "This is image button"; //This should be whatever HTML you want for your image-based button
}
class InputButton extends Button {
	protected $_html = "This is input button"; //This should be whatever HTML you want for your normal button (<input type="button"... />);
}
class FlashButton extends Button {
	protected $_html = "This is Flash Button"; //This should be whatever HTML you want for your flash-based button
}
// Second Part

class ButtonFactory
{
    public static function createButton($type)
    {
        $baseClass = 'Button';
        $targetClass = ucfirst($type).$baseClass;
        if (class_exists($targetClass) && is_subclass_of($targetClass, $baseClass)) {
            return new $targetClass;
		} else {
            throw new Exception("The button type '$type' is not recognized.");
		}
    }
}
//$buttons = array('image');
$buttons = array('input');
//$buttons = array('flash');
foreach($buttons as $b) {
    echo ButtonFactory::createButton($b)->getHtml();
}
?>

Factory Pattern: using & abusing

  • Use the Factory Method only if you really need it
  • Don’t anticipate future needs, refactoring is usually the right choice Plans might change and you just spent time building useless, heavy infrastructures
  • Be Smart! Be Agile! Be Lazy!
Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I graduated in 2009 with a bachelor’s degree in Engineering from State University Of Bangladesh, I’m also a Certified Engineer on ZEND PHP 5.3, I served my first five years a number of leadership positions at Winux Soft Ltd, SSL Wireless Ltd, CIDA and MAX Group where I worked on ERP software and web development., but now i’m a co-founder and Chief Executive Officer and Managing Director of TechBeeo Software Consultancy Services Ltd. I’m also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute – a leading Training Institute in the country.

Leave a Reply

Your email address will not be published. Required fields are marked *