PHP Design Patterns .

PHP Design Patterns Abstract Factory

About the Abstract Factory


In the Abstract Factory Pattern, an abstract factory defines what objects the non-abstract or concrete factory will need to be able to create.

The concrete factory must create the correct objects for it's context, insuring that all objects created by the concrete factory have been chosen to be able to work correctly for a given circumstance.

In this example we have an abstract factory, AbstractBookFactory, that specifies two classes, AbstractPHPBook and AbstractMySQLBook, which will need to be created by the concrete factory.

The concrete class OReillyBookfactory extends AbstractBookFactory, and can create the OReillyMySQLBook and OReillyPHPBook classes, which are the correct classes for the context of OReilly.


AbstractBookFactory.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

abstract class AbstractBookFactory { abstract function makePHPBook(); abstract function makeMySQLBook(); }
To download source right-click here and "Save As...".


OReillyBookFactory.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

include_once('AbstractMySQLBook.php'); class OReillyMySQLBook extends AbstractMySQLBook { private $author; private $title; function __construct() { $this->author = 'George Reese, Randy Jay Yarger, and Tim King'; $this->title = 'Managing and Using MySQL'; } function getAuthor() {return $this->author;} function getTitle() {return $this->title;} }
To download source right-click here and "Save As...".


SamsBookFactory.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved

include_once('AbstractBookFactory.php'); include_once('SamsPHPBook.php'); include_once('SamsMySQLBook.php'); class SamsBookFactory extends AbstractBookFactory { private $context = "Sams"; function makePHPBook() {return new SamsPHPBook;} function makeMySQLBook() {return new SamsMySQLBook;} }
To download source right-click here and "Save As...".


AbstractBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved
  
    abstract class AbstractBook {
  
    abstract function getAuthor();
    
    abstract function getTitle();
  
  }
To download source right-click here and "Save As...".


AbstractMySQLBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved
  
    include_once('AbstractBook.php');
  
    abstract class AbstractMySQLBook {
  
    private $subject = "MySQL";
  
  }
To download source right-click here and "Save As...".


OReillyMySQLBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

include_once('AbstractMySQLBook.php'); class OReillyMySQLBook extends AbstractMySQLBook { private $author; private $title; function __construct() { $this->author = 'George Reese, Randy Jay Yarger, and Tim King'; $this->title = 'Managing and Using MySQL'; } function getAuthor() {return $this->author;} function getTitle() {return $this->title;} }
To download source right-click here and "Save As...".


SamsMySQLBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

include_once('AbstractMySQLBook.php'); class SamsMySQLBook extends AbstractMySQLBook { private $author; private $title; function __construct() { $this->author = 'Paul Dubois'; $this->title = 'MySQL, 3rd Edition'; } function getAuthor() {return $this->author;} function getTitle() {return $this->title;} }
To download source right-click here and "Save As...".


AbstractPHPBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved
  
    include_once('AbstractBook.php');
  
    abstract class AbstractPHPBook {
  
    private $subject = "PHP";
  
  }
To download source right-click here and "Save As...".


OReillyPHPBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

include_once('AbstractPHPBook.php'); class OReillyPHPBook extends AbstractPHPBook { private $author; private $title; private static $oddOrEven = 'odd'; function __construct() { //alternate between 2 books if ('odd' == self::$oddOrEven) { $this->author = 'Rasmus Lerdorf and Kevin Tatroe'; $this->title = 'Programming PHP'; self::$oddOrEven = 'even'; } else { $this->author = 'David Sklar and Adam Trachtenberg'; $this->title = 'PHP Cookbook'; self::$oddOrEven = 'odd'; } } function getAuthor() {return $this->author;} function getTitle() {return $this->title;} }
To download source right-click here and "Save As...".


SamsPHPBook.php

//copyright Lawrence Truett and FluffyCat.com 2007, all rights reserved

include_once('AbstractPHPBook.php'); class SamsPHPBook extends AbstractPHPBook { private $author; private $title; function __construct() { //alternate randomly between 2 books mt_srand((double)microtime()*10000000); $rand_num = mt_rand(0,1); if (1 > $rand_num) { $this->author = 'George Schlossnagle'; $this->title = 'Advanced PHP Programming'; } else { $this->author = 'Christian Wenz'; $this->title = 'PHP Phrasebook'; } } function getAuthor() {return $this->author;} function getTitle() {return $this->title;} }
To download source right-click here and "Save As...".


testAbstractFactory.php

//copyright Lawrence Truett and FluffyCat.com 2005, all rights reserved

include_once('OReillyBookFactory.php'); include_once('SamsBookFactory.php');

echo tagins("html"); echo tagins("head"); echo tagins("/head"); echo tagins("body");

echo "BEGIN TESTING ABSTRACT FACTORY PATTERN"; echo tagins("br").tagins("br"); echo 'testing OReillyBookFactory'.tagins("br"); $bookFactoryInstance = new OReillyBookFactory; testConcreteFactory($bookFactoryInstance); echo tagins("br"); echo 'testing SamsBookFactory'.tagins("br"); $bookFactoryInstance = new SamsBookFactory; testConcreteFactory($bookFactoryInstance); echo tagins("br"); echo "END TESTING ABSTRACT FACTORY PATTERN"; echo tagins("br"); echo tagins("/body"); echo tagins("/html");

function testConcreteFactory($bookFactoryInstance) { $phpBookOne = $bookFactoryInstance->makePHPBook(); echo 'first php Author: '. $phpBookOne->getAuthor().tagins("br"); echo 'first php Title: '. $phpBookOne->getTitle().tagins("br"); $phpBookTwo = $bookFactoryInstance->makePHPBook(); echo 'second php Author: '. $phpBookTwo->getAuthor().tagins("br"); echo 'second php Title: '. $phpBookTwo->getTitle().tagins("br"); $mySqlBook = $bookFactoryInstance->makeMySQLBook(); echo 'MySQL Author: '. $mySqlBook->getAuthor().tagins("br"); echo 'MySQL Title: '. $mySqlBook->getTitle().tagins("br"); } //doing this so code can be displayed without breaks function tagins($stuffing) { return "<".$stuffing.">"; }
To download source right-click here and "Save As...".

output of testAbstractFactory.php

BEGIN TESTING ABSTRACT FACTORY PATTERN

testing OReillyBookFactory first php Author: Rasmus Lerdorf and Kevin Tatroe first php Title: Programming PHP second php Author: David Sklar and Adam Trachtenberg second php Title: PHP Cookbook MySQL Author: George Reese, Randy Jay Yarger, and Tim King MySQL Title: Managing and Using MySQL

testing SamsBookFactory first php Author: Christian Wenz first php Title: PHP Phrasebook second php Author: George Schlossnagle second php Title: Advanced PHP Programming MySQL Author: Paul Dubois MySQL Title: MySQL, 3rd Edition

END TESTING ABSTRACT FACTORY PATTERN

References


Design Patterns
Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides

PHP 5
The Official PHP web site
Core PHP Programming, 3rd Edition by Leon Atkinson and Zeev Suraski
Comments Comments are left by visitors to FluffyCat.com and may or may not be accurate.
Comment by Serhiy7 on 2016-11-08 Rate this Comment

When I type in Google php design patterns I've found your site on top of first page. I've read it several times and was close to think I'm very poor-minded person. I couldnt understand how it works. Till I've found OReillyBookFactory.php code is different with site in downloaded source. So its very stupid your site.

Comment by slayersilence on 2013-05-22 Rate this Comment

because there is no plural heritage file<AbstractBook.php> can be done like this:

interface AbstractBook
{
function getAuthor();
function getTitle();
}

and use like:

class OReillyMySQLBook extends AbstractMySQLBook implements AbstractBook
{
private $author;
private $title;

function __construct()
{
$this->author = 'George Reese, Randy Jay Yarger, and Tim King';
$this->title = 'Managing and Using MySQL';
}
function getAuthor() {return $this->author;}
function getTitle() {return $this->title;}
}
class SamsMySQLBook extends AbstractMySQLBook implements AbstractBook
{
private $author;
private $title;

function __construct()
{
$this->author = 'Paul Dubois';
$this->title = 'MySQL, 3rd Edition';
}
function getAuthor() {return $this->author;}
function getTitle() {return $this->title;}
}

Comment by slayersilence on 2016-09-11 Rate this Comment

file <OReillyBookFactory.php> change to:

class OReillyBookFactory extends AbstractBookFactory
{
private $context = "OReilly";

function makePHPBook() {return new OReillyPHPBook;}
function makeMySQLBook() {return new OReillyMySQLBook;}
}
p.s. excellent examples for beginners.

Comment by milh_cbt on 2013-02-01 Rate this Comment

hi,
I'm new to PHP, but experienced with java. I this path of code mistaken.
you wrote
abstract class AbstractMySQLBook {
it should be
class OReillyMySQLBook extends AbstractMySQLBook {
so the phpbook one.

Comment by Leonardo on 2013-05-22 Rate this Comment

Hi!

In the Design Patterns Abstract Factory, the Class AbstractMySQLBook should be to inherit from AbstractBook.
Same for AbstractPHPBook.

The code run well because AbstractBook only define protocol, and the concrete class implement it.

Bye and thank Yuo very much for the examples!

Leoanrdo

 
Sign in to comment on PHP Design Patterns Abstract Factory.