The “Missing” Patterns of the PHP Manual

Gladly some pattern code has been removed from the PHP Manual. Not so gladly, it’s just gone, including user comments.

The not so good part of the story is, that the two patterns that were given in the manual page were the Parameterized Factory Method and the Singleton. Both could be considered an Anti-Pattern actually so it’s probably good they don’t have “support” inside the PHP Manual any longer as having them in there could be misread – but actually what could not be misread?! And take care, this is just a copy, I’m not judging whether those “patterns” are correct, working or whatever. The list:

Parameterized Factory Method

The Factory pattern allows for the instantiation of objects at runtime. It is called a Factory Pattern since it is responsible for “manufacturing” an object. A Parameterized Factory receives the name of the class to instantiate as argument.

<?php
class Example
{
    // The parameterized factory method
    public static function factory($type)
    {
        if (include_once 'Drivers/' . $type . '.php') {
            $classname = 'Driver_' . $type;
            return new $classname;
        } else {
            throw new Exception('Driver not found');
        }
    }
}

// Load a MySQL Driver
$mysql = Example::factory('MySQL');

// Load an SQLite Driver
$sqlite = Example::factory('SQLite');
?>

Singleton

The Singleton ensures that there can be only one instance of a Class and provides a global access point to that instance. Singleton is a “Gang of Four” Creational Pattern.

The Singleton pattern is often implemented in Database Classes, Loggers, Front Controllers or Request and Response objects.

There are multiple notes which I think should be given before the example, not afterwards:

  • The Singleton pattern is one of the more controversial patterns. Critics argue that Singletons introduce Global State into an application and tightly couple the Singleton and its consuming classes. This leads to hidden dependencies and unexpected side-effects, which in turn leads to code that is harder to test and maintain.
  • Critics further argue that it is pointless to use a Singleton in a Shared Nothing Architecture like PHP where objects are unique within the Request only anyways. It is easier and cleaner to create collaborator object graphs by using Builders and Factory patterns once at the beginning of the Request.
  • Singletons also violate several of the “SOLID” OOP design principles and the Law of Demeter. Singletons cannot be serialized. They cannot be subtyped (before PHP 5.3) and won’t be Garbage Collected because of the instance being stored as a static attribute of the Singleton.
<?php
class Example
{
    private static $instance;
    private $count = 0;

    private function __construct()
    {
    }

    public static function singleton()
    {
        if (!isset(self::$instance)) {
            echo 'Creating new instance.';
            $className = __CLASS__;
            self::$instance = new $className;
        }
        return self::$instance;
    }

    public function increment()
    {
        return $this->count++;
    }

    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

    public function __wakeup()
    {
        trigger_error('Unserializing is not allowed.', E_USER_ERROR);
    }
}

$singleton = Example::singleton(); // prints "Creating new instance."
echo $singleton->increment(); // 0
echo $singleton->increment(); // 1

$singleton = Example::singleton(); // reuses existing instance now
echo $singleton->increment(); // 2
echo $singleton->increment(); // 3

// all of these will raise a Fatal Error
$singleton2 = new Example;
$singleton3 = clone $singleton;
$singleton4 = unserialize(serialize($singleton));
?>

Command Pattern

(by Geliscan; 03 Dec 2011) This is a simple Command Pattern example which performs Undo operation on a calculator. You may use callbacks in order to verify open-close principle.

<?php
abstract class Command {
    abstract public function unExecute ();
    abstract public function Execute ();
}
class concreteCommand extends Command {
    private $operator,$operand,$calculator;
    public function __construct ($calculator,$operator,$operand) {
        $this->operator = $operator;
        $this->operand = $operand;
        $this->calculator = $calculator;
    }
    public function Execute() {
        $this->calculator->Action($this->operator,$this->operand);
    }
    public function unExecute () {
        $this->calculator->Action($this->Undo($this->operator),$this->operand);
    }
    private function Undo ($operator) {
        switch ($operator) {
            case '+': return '-';
            case '-': return '+';
            case '*': return '/';
            case '/': return '*';
        }
    }
}
class Calculator {
    private $current;
    public function __construct() {
        $this->current = 0;
    }
    public function Action($operator,$operand) {
        switch ($operator) {
            case '+':
                $this->current += $operand;
                break;
            case '-':
                $this->current -= $operand;
                break;
            case '*':
                $this->current *= $operand;
                break;
            case '/':
                $this->current /= $operand;
                break;
        }
    }
    public function getCurrent() {
        return $this->current;
    }
}
class Invoker {
    private $commands,$calculator,$current;
    public function __construct() {
        $current =-1;
    }
    public function Undo() {
        if ($this->current >= 0) {
            $this->commands[$this->current]->unExecute();
            $this->current--;
        }
    }
    public function Compute($command) {
        $command->Execute();
        $this->current++;
        $this->commands[$this->current] = $command;
    }
}

$User = new Invoker();
$calculator = new Calculator();
$command = new concreteCommand($calculator,'+',5);
$User->Compute($command);
echo "After +5: ".$calculator->getCurrent()."<br/>"; # After +5: 5
$command = new concreteCommand($calculator,'*',7);
$User->Compute($command);
echo "After *7: ".$calculator->getCurrent()."<br/>"; # After *7: 35
$command = new concreteCommand($calculator,'/',2);
$User->Compute($command);
echo "After /2: ".$calculator->getCurrent()."<br/>"; # After /2: 17.5
$command = new concreteCommand($calculator,'-',10);
$User->Compute($command);
echo "After -10: ".$calculator->getCurrent()."<br/>"; # After -10: 7.5
$User->Undo();
echo "Undo Operation: ".$calculator->getCurrent()."<br/>"; # Undo Operation: 17.5
$User->Undo();
echo "Undo Operation: ".$calculator->getCurrent()."<br/>"; # Undo Operation: 35
$User->Undo();
echo "Undo Operation: ".$calculator->getCurrent()."<br/>"; # Undo Operation: 5
$User->Undo();
echo "Undo Operation: ".$calculator->getCurrent()."<br/>";

?>

Lazy Initialization

(by SJH; 21 Jan 2011) The problem with the singleton pattern is that there aren’t really many cases where it is a true singleton.

There are many cases where you want to get access to a specific object that is the same each time.
For example accessing objects that have different drivers.

In this instance its better to use the Lazy Initialization pattern:

<?php 
abstract function Lazy_Initialization_Object {
    /* Set up the array of instances */
    protected static $instances = array();

    /** Make sure the constructor isn't accessible to 
     * the rest of the world 
     */
    private function __construct() {}

    /**
     * Returns a specific object that relies on the 
     * parameter passed
     *
     * @param string class name to be returned
     * @throws Exception if $type doesn't extend __CLASS__
     */
    public function get_object($type) {
        $reflection_class = new ReflectionClass($type);

        // Check if the object is a Lazy Iinitialization Object
        if( ! $reflection_class->isSubclassOf(__CLASS__))
            throw Exception("$type does not extend __CLASS__");

        // Check if the object already exists in the pool 
        if( ! array_key_exists($type,self::$instances)) {
          // If not initialise a new one and place it in the pool
            self::$instances[$type]=$reflection_class->newInstance();
        }

        // Return the object you want 
        return self::$instances[$type]    

    }

    /** Specify all the functions that these drivers have in common */
    public abstract function initialize($name);

    public function display() {

       echo $content
    }

    protected $content;
}

class Person_Driver_HTML extends Lazy_Initialization_Object {
    
   public function initialize($name) {
         $content = "<p>Name: $name</p>";
   }

}

class Person_Driver_Raw extends Lazy_Initialization_Object {
    public function initialize($name) {
         $content = "name: $name";
    } 

}

Lazy_Initialization_Object::
    get_object("Person_Driver_Raw")->initialize("fifi");

Lazy_Initialization_Object::
    get_object("Person_Driver_HTML")->initialize("fifi");

Lazy_Initialization_Object::
    get_object("Person_Driver_HTML")->display(); 
// will output "<p>Name: fifi</p>"
Lazy_Initialization_Object::
    get_object("Person_Driver_Raw")->display(); 
// will output "name: fifi";

echo Lazy_Initialization_Object::
         get_object("Person_Driver_HTML") === 
     Lazy_Initialization_Object::
         get_object("Person_Driver_HTML"); // TRUE

echo Lazy_Initialization_Object::
         get_object("Person_Driver_HTML") === 
     Lazy_Initialization_Object::
         get_object("Person_Driver_Raw"); // FALSE

?>

Decorator

(by Edgar; 13 Jul 2009) Example of a decorator, which adds array access to any object:

<?php

class ArrayAccessDecorator implements ArrayAccess {
        protected $object = null;
        public function __construct($object){
                $this->object = $object;
        }
        public function __call($method, $args){
                return $this->productpart->$method($args);
        }
        public function __set($key, $val){
                $this->object->$key = $val;
        }
        public function __get($key){
                return $this->object->$key;
        }
        /* ArrayAccess */
        public function offsetSet($key, $value){
                $this->__set($key, $value);
        }
        public function offsetGet($key){
                return $this->__get($key);
        }
        public function offsetUnset($key){
                $this->__set($key, null);
        }
        public function offsetExists($offset){

                        $test = $this->object->__get($offset);
                        if($test !== null){
                                return true;
                        } else {
                                return false;
                        }
        }
}

$stdobject = (object)array('test'=>'test', 'test2' => 'test2');
$arr = new ArrayAccessDecorator($stdobject);
print $arr['test']; // test
$arr['test'] = 'hello';
print $arr['test']; // hello
?>

(by Anonymous; 29 Sep 2008) Let me describe another pattern it is called “Decorator”. It can be used to add features to already written object. It is useful for extending some library classes from your framework without changing the original classes (especially if somebody else wrote those). The actual meaning is best presented in an example.

<?php 
// the main interface in which we going to do some decoration
interface salad{
    public function wait();
}

// main class which is already defined and you can't or don't want to change
class shopSalad implements salad{
    private $tomatoes;
    private $cucumbers;
    private $cheese;
    
    public function __construct($tomatoes, $cucumbers, $cheese){
        $this->tomatoes = $tomatoes;
        $this->cucumbers = $cucumbers;
        $this->cheese = $cheese; 
    }
    
    public function wait(){
        echo "the salad is served using {$this->tomatoes} tomatoes, {$this->cucumbers} cucumbers and {$this->cheese} gr. of cheese.";
    }
}

// abstract decorator class - note that it implements salad
abstract class saladDecorator implements salad{
    protected $salad;  // the object for decoration
    public function __construct(salad $salad){
        $this->salad=$salad;
    }
    // there is no need to mention the wait function therefore this class inherits the original salad
    // the purpose of this class is maintaining the type of the object produced by the decorators.
    // it inherits the same interface as the original and it will be inherited by the concrete decorators
}

// sauce decorator
class saladSauce extends saladDecorator {
    public function wait(){
        $this->salad->wait();
        echo " Then it was decorated with some sauce.";
        
    }
}

// onions decorator
class saladOnions extends saladDecorator {
    public function wait(){
        $this->salad->wait();
        echo " Then it was decorated with some onions.";
    }
}

$order1 = new shopSalad(2,1,100); // creates the salad in the normal way
$order1 = new saladSauce($order1); // add a decorator to the class
$order1->wait();
echo '<br />';

// or
$order3 = new saladOnions(new saladSauce(new shopSalad(1,0.5,50))); // you don't need to load a variable with the reference
$order3->wait();
?>

this will outputs:
the salad is served using 2 tomatoes, 1 cucumbers and 100 gr. of cheese. Then it was decorated with some sauce.
the salad is served using 3 tomatoes, 2 cucumbers and 100 gr. of cheese. Then it was decorated with some onions. Then it was decorated with some sauce.
the salad is served using 1 tomatoes, 0.5 cucumbers and 50 gr. of cheese. Then it was decorated with some souse. Then it was decorated with some onions.

The pattern is not intended to be used with simple object and I couldn’t do more simple than that. The pattern is useful in every way when the extending of an object is required. It can be used to divide some methods from others or to create layers of interaction with the object. In example if you have an file interface and a imageFile class which implements the file and then you can have also an textFile for the textFile you can do some layering and if you want to read the file as XML you can mace a decorator to do so. The XML decorator will inherit the interface file so you can save it and the instance of textFile will be given to create the decorator so you can read the actual text and pars it as XML. It is possible the file to be .ini or some other text based document and you can make a decorator for every one of them. This is the actual benefit of the pattern.

Composite Pattern

(by Dario Ocles; 18 Jun 2007) This’s a example of Composite Pattern:

<?php
abstract class Graphic{
    abstract public function draw();
}

class Triangle extends Graphic{
    private $name = '';

    public function __construct($name = 'unknown'){
        $this->name = $name;
    }

    public function draw(){
        echo '-I\'m a triangle '.$this->name.'.<br>';
    }
}

class Container extends Graphic{
    private $name = '';
    private $container = array();

    public function __construct($name = 'unknown'){
        $this->name = $name;
    }

    public function draw(){
        echo 'I\'m a container '.$this->name.'.<br>';
        foreach($this->container as $graphic)
            $graphic->draw();
    }

    public function add(Graphic $graphic){
        $this->container[] = $graphic;
    }

    public function del(Graphic $graphic){
        unset($this->container[$graphic]);
    }
}

$tri1 = new Triangle('1');
$tri2 = new Triangle('2');
$tri3 = new Triangle('3');

$container1 = new Container('1');
$container2 = new Container('2');
$container3 = new Container('3');

$container1->add($tri1);
$container1->add($tri2);
$container2->add($tri3);

$container3->add($container1);
$container3->add($container2);

$container3->draw();
?>

The above example will output:

I’m a container 3.
I’m a container 1.
-I’m a triangle 1.
-I’m a triangle 2.
I’m a container 2.
-I’m a triangle 3.


Credits belong to the original authors, published under license (Creative Commons Attribution 3.0 License, copyright (c) the PHP Documentation Group).

This entry was posted in PHP Development, Pressed and tagged , , , , , , , , , . Bookmark the permalink.

3 Responses to The “Missing” Patterns of the PHP Manual

  1. Hi @hakre,

    Nice article. You made a comment that peaked my interest though, that “Parameterized Factory Method could be considered an Anti-Pattern.” That’s the first I’ve heard that and I google for it and couldn’t find anything that referred to it as an anti-pattern.

    If it indeed is considered by some to be anti-pattern I’d like to read any discussion about it. Do you have a link? Thanks in advance.

    -Mike

    • hakre says:

      Well, this was in a discussion we had in the PHP chat on SO mainly, which inspired me to create the post as well. This sort of “judgement” might be a bit harsh and subject to discussion. If you take for example my WordPress Plugin: How do I avoid “tight coupling”? answer, it has that (anti-) pattern, too. As it shows it sits on the border and is only triggered as the application is set up. I’d say you should prevent calling these methods later on or better, inside a distinct part of your application because it is similar to the new keyword. So the dangerous part with it is that you might think “oh it’s practical, let’s use it everywhere” while you should only use it to solve a very specific problem. Similar with the singleton, hordes of PHP coders made it their “favourite pattern” just for the sake of it being simple.

  2. Pingback: Gary Jones’ Recommended Resources on Avoiding Singletons

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.