Skip to main content

Factory Method Pattern

Official definition :

Defines an interface for creating an object, but lets subclass decide which class to instantiate. Factory method lets a class defer instantiation to subclass.

So factory method pattern is a pattern that manipulate the product functionality but not instantiate the product object, a subclass take decision to make which class it instantiate by extend or implement the abstract creator class. Abstract creator class has no knowledge of the actual product that will be created.Object creation is totally depend on subclass.

For example


abstract class  PizzaStore
{
    public function orderPizza($type) {

        $piza = null;
        $piza = $this->createPizza($type);

        $piza->prepare();
        $piza->bake();
        $piza->cut();
        $piza->box();
        return $piza;

    }

    abstract function createPizza($type);
}

Here PizzaStore our main AbstractCreator class which extent by Concrete Subclass NyStylePizzaStore. And NyStylePizzaStore class take decision to make which class it will instantiate.


class NyStylePizzaStore extends PizzaStore
{

    function createPizza($type)
    {
        if ($type == "chesse") {
            return new NyStyleChessePizza();
        } else if ($type == "peporoni") {
            return new NyStylePeporoniPizza();
        } else if ($type == "clam") {
            return new NyStyleClamPizza();
        } else if ($type == "veggie") {
            return new NyStyleVeggiePizza();
        } else {
            return null;
        }
    }
}





class NyStyleClamPizza extends Pizza
{

    public function __construct()
    {
        $this->storeName = "NyStyle";
    }
}

/**
 * Pizza File
 *
 * @author Md.Atiqul haque <md_atiqulhaque@yahoo.com>
 */




abstract class Pizza implements Store
{
    protected $storeName;

    public function bake()
    {
        echo  "----" . "Baking....<br>";
    }

    public function prepare()
    {
        echo "----" . "Preparing piza for {$this->storeName}...<br>";
    }

    public function cut()
    {
        echo "----" . "Cutting...<br>";
    }

    public function box()
    {
        echo  "----" . "Boxing...<br>";
    }

    public function getName()
    {
        return $this->storeName;
    }
}


/**
 * Store File
 *
 * @author Md.Atiqul haque <md_atiqulhaque@yahoo.com>
 */




interface Store
{
    public function bake();

    public function prepare();

    public function cut();

    public function box();
}

$pizaStore = new NyStylePizzaStore();

$pizaStore->orderPizza('clam');

Out put will be
—-Preparing piza for NyStyle…
—-Baking….
—-Cutting…
—-Boxing…

DecoratorPattern


interface DecoratorInterface
{
    /**
     * @return mixed
     */
    public function render();
}






class HTMLDecorator implements DecoratorInterface
{
    protected $book = null;

    public function __construct($book_object)
    {
        $this->book = $book_object;
    }

    public function render()
    {
        $properties = get_object_vars($this->book);

        echo '<ul>';
        foreach($properties as $key => $value) {
            echo '<li>' . $key . ' -- ' . $value . '</li>';
        }
        echo '</ul>';
    }
}




class JSONDecorator implements DecoratorInterface
{
    protected $book = null;

    public function __construct($book_object)
    {
        $this->book = $book_object;
    }

    public function render()
    {
        echo json_encode($this->book);
    }
}






class PatternTest {

    public $decorator;

    public function __construct(DecoratorInterface $decorator)
    {
        $this->decorator = $decorator;
    }
}


$book = new stdClass();
$book->title = "Patterns of Enterprise Application Architecture";
$book->author_first_name = "Martin";
$book->author_last_name = "Fowler";

echo '<h1>HTML Decorator</h1>';

$htmlDecorator = new HTMLDecorator($book);
$htmlDecorator->render();

echo '<h1>JSON Decorator</h1>';

$jsonDecorator = new JSONDecorator($book);
$jsonDecorator->render();