PHP Decorator Pattern Example
Fri, 22 Oct 2010Here is a simple PHP Decorator Pattern Example. Go ahead and dissect this script to see how it works. A decorator pattern is exactly what it sounds like, it decorates! So in this example we'll make a cupcake that we add items onto, and this changes the instance of the original object -- and we don't need to extend a ton of classes!
By playing around with this basic thing, you should be able to learn by simple example. I hope it helps anyone learning OOD!
<?php
// 1. Our base object that gets decorations on it
class Cupcake
{
public $Toppings = array('sprinkles' => 0, 'frosting' => 'none');
public function __construct($int, $str)
{
$this->Toppings['sprinkles'] = $int;
$this->Toppings['frosting'] = $str;
}
}
// 2. Just a nice little wrapper to keep the decorators consistent!
abstract class Decorator_Wrapper
{
abstract function Add($mixed);
abstract function Remove($mixed);
}
// 3. A decorator that manipulates our main object!
class Sprinkle_Decorator extends Decorator_Wrapper
{
public function __construct(Cupcake $c)
{
$this->Cupcake = $c;
}
public function Add($int)
{
$this->Cupcake->Toppings['sprinkles'] += $int;
}
public function Remove($int)
{
$this->Cupcake->Toppings['sprinkles'] -= $int;
}
}
// 4. Another decorator that manipulates our main object!
class Frosting_Decorator extends Decorator_Wrapper
{
public function __construct(Cupcake $c)
{
$this->Cupcake = $c;
}
public function Add($str)
{
$this->Cupcake->Toppings['frosting'] = $str;
}
public function Remove($str)
{
echo "Hrmm.. We cant seem to remove your $str, it's stuck on the muffin!";
}
}
// Run through some tests to satisfy our customer!
echo '<p>Mmm! I want a cupcake!</p>';
$cupcake = new Cupcake(5, 'none');
print_r($cupcake->Toppings);
echo '<p>Hey, I want more sprinkles!</p>' ;
$sprinkle = new Sprinkle_Decorator($cupcake);
$sprinkle->Add('55');
print_r($cupcake->Toppings);
echo '<p>Not so many!</p>' ;
$sprinkle->Remove('25');
print_r($cupcake->Toppings);
echo '<p>If only I had some frosting :)</p>';
$frosting = new Frosting_Decorator($cupcake);
$frosting->Add('Chocolate');
print_r($cupcake->Toppings);
And here's the output!
Mmm! I want a cupcake!
Array ( [sprinkles] => 5 [frosting] => none )Hey, I want more sprinkles!
Array ( [sprinkles] => 60 [frosting] => none )Not so many!
Array ( [sprinkles] => 35 [frosting] => none )If only I had some frosting :)
Array ( [sprinkles] => 35 [frosting] => Chocolate )And here's a video explaining the pattern some more!