# 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
```php
interface Coffee {
    public function getCost();
    public function getDescription();
}
```

### Concrete Component
```php
class SimpleCoffee implements Coffee {
    public function getCost() {
        return 10;
    }

    public function getDescription() {
        return "Simple Coffee";
    }
}
```

### The Decorators
```php
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
```php
$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
```

[[programming/php/php]] [[programming/php/php-design-patterns]]