Last active
August 29, 2015 13:57
-
-
Save thelowlypeon/9585326 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Our base Coffee class, which has a cost, array of ingredients, | |
* and getters/setters. Note that this class is not extended or | |
* implemented, and decorators don't modify Coffee objects. | |
*/ | |
class Coffee { | |
private $cost; | |
private $ingredients = array(); | |
public function __construct($cost, $ingredients=array('coffee')) { | |
$this->cost = $cost; | |
if (!is_array($ingredients)) { | |
$ingredients = array($ingredients); | |
} | |
$this->ingredients = $ingredients; | |
} | |
public function getCost() { return $this->cost; } | |
public function getIngredients() { return $this->ingredients; } | |
} | |
/** | |
* Our base decorator class. In this example, the CoffeeDecorator is | |
* not an abstract class, though an alternate approach is to make the decorator | |
* abstract and then make each decorator extend it. | |
*/ | |
class CoffeeDecorator { | |
protected $coffee; | |
protected $cost; | |
protected $ingredients = array(); | |
public function __construct(Coffee $coffee) { | |
$this->coffee = $coffee; | |
$this->setCost(); | |
$this->setIngredients(); | |
} | |
public function setCost() { | |
$this->cost = $this->coffee->getCost(); | |
} | |
public function setIngredients() { | |
$this->ingredients = $this->coffee->getIngredients(); | |
} | |
public function getCost() { return $this->cost; } | |
public function getIngredients() { return $this->ingredients; } | |
public function getSortedIngredients() { | |
$ingredients = $this->getIngredients(); | |
$arr = array(); | |
foreach ($ingredients as $ingredient) { | |
$arr[$ingredient] = (array_key_exists($ingredient, $arr) ? $arr[$ingredient] : 0) + 1; | |
} | |
return $arr; | |
} | |
} | |
/** | |
* Here's our first decorator. Creating a MilkyCoffee will add | |
* milk to the ingredients, as well as a corresponding cost. | |
* | |
* Note again that this will not modify the original Coffee class. | |
*/ | |
class MilkyCoffee extends CoffeeDecorator { | |
private $decorator; | |
protected $cost = 1; | |
protected $ingredients = array('Milk'); | |
public function __construct(CoffeeDecorator $decorator) { | |
$this->decorator = $decorator; | |
$this->addMilk(); | |
} | |
public function addMilk() { | |
$this->decorator->cost = $this->decorator->getCost() + $this->cost; | |
$this->decorator->ingredients = array_merge($this->ingredients, $this->decorator->getIngredients()); | |
} | |
} | |
/** | |
* Like this MilkyCoffee decorator, this will add a cost and ingredients. | |
*/ | |
class FoamyCoffee extends CoffeeDecorator { | |
private $decorator; | |
protected $cost = .5; | |
protected $ingredients = array('Steam', 'Milk'); | |
public function __construct(CoffeeDecorator $decorator) { | |
$this->decorator = $decorator; | |
$this->addFoam(); | |
} | |
public function addFoam() { | |
$this->decorator->cost = $this->decorator->getCost() + $this->cost; | |
$this->decorator->ingredients = array_merge($this->ingredients, $this->decorator->getIngredients()); | |
} | |
} | |
/** | |
* Let's make some coffee | |
*/ | |
function run() { | |
$coffee = new Coffee(1); | |
$decorator = new CoffeeDecorator($coffee); | |
echo "\n-------------\ninitial coffee: ($" . $coffee->getCost() . "):\n " . json_encode($coffee->getIngredients()) . "\n"; | |
$milky = new MilkyCoffee($decorator); | |
echo "\nmilky coffee ($" . $decorator->getCost() . "):\n " . json_encode($decorator->getSortedIngredients()) . "\n"; | |
$foamy = new FoamyCoffee($decorator); | |
echo "\nfoamy, milky coffee ($" . $decorator->getCost() . "):\n " . json_encode($decorator->getSortedIngredients()) . "\n"; | |
echo "\n(adding foam...)"; | |
$foamy->addFoam(); | |
echo "\nsuper foamy, milky coffee: ($" . $decorator->getCost() . "):\n " . json_encode($decorator->getSortedIngredients()) . "\n"; | |
echo "\nbase coffee: ($" . $coffee->getCost() . "):\n " . json_encode($coffee->getIngredients()); | |
echo "\n-------------\n"; | |
} | |
run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment