Design patterns: Decorator
The Decorator pattern lets you add behavior to an object dynamically.
Characteristics of the Decorator pattern
- Dynamic addition of behavior: The Decorator Pattern lets you add new behaviors and responsibilities to existing objects dynamically, without altering the original code.
- Flexible composition: It lets you combine different decorators to extend an object’s functionality, offering great flexibility when building complex behaviors.
- Follows the Open/Closed Principle: It follows the open/closed principle, letting you extend the functionality of objects without modifying existing code. You can add decorators without changing the original classes.
- Support for complex objects: It makes it easy to manage objects with many variations and options, letting you create complex configurations without needing a static class hierarchy.
- Unified interface: Decorated objects and original objects implement the same interface, so clients can use decorated and undecorated objects interchangeably, without worrying about implementation differences.
Example in PHP:
interface Coffee {
public function cost();
}
class BasicCoffee implements Coffee {
public function cost() {
return 5;
}
}
class MilkDecorator implements Coffee {
private $coffee;
public function __construct(Coffee $coffee) {
$this->coffee = $coffee;
}
public function cost() {
return $this->coffee->cost() + 2; // Adds the cost of the milk
}
}
// Usage
$basicCoffee = new BasicCoffee();
$milkCoffee = new MilkDecorator($basicCoffee);
echo $milkCoffee->cost(); // 7 (5 + 2)