PHP Decorator Pattern
The Decorator pattern is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors.
1. Concept
- Component: The interface for objects that can have responsibilities added to them dynamically.
- Concrete Component: Defines an object to which additional responsibilities can be attached.
- Decorator: Maintains a reference to a Component object and defines an interface that conforms to Component's interface.
2. Example: Coffee Shop
Imagine a coffee shop where you can add various ingredients (decorators) to a base coffee.
The Interface
interface Coffee {
public function getCost();
public function getDescription();
}
Concrete Component
class SimpleCoffee implements Coffee {
public function getCost() {
return 10;
}
public function getDescription() {
return "Simple Coffee";
}
}
The Decorators
class MilkDecorator implements Coffee {
protected $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function getCost() {
return $this->coffee->getCost() + 2;
}
public function getDescription() {
return $this->coffee->getDescription() . ", Milk";
}
}
class WhipDecorator implements Coffee {
protected $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function getCost() {
return $this->coffee->getCost() + 5;
}
public function getDescription() {
return $this->coffee->getDescription() . ", Whip";
}
}
Usage
$myCoffee = new SimpleCoffee();
echo $myCoffee->getCost(); // 10
echo $myCoffee->getDescription(); // Simple Coffee
$myCoffee = new MilkDecorator($myCoffee);
echo $myCoffee->getCost(); // 12
echo $myCoffee->getDescription(); // Simple Coffee, Milk
$myCoffee = new WhipDecorator($myCoffee);
echo $myCoffee->getCost(); // 17
echo $myCoffee->getDescription(); // Simple Coffee, Milk, Whip