A decorator wraps a dependency implementing the same contract to extend its behavior.
What It Does
A decorator wraps a dependency implementing the same contract to extend its behavior. The following examples distinguish a normal use case, a boundary case and a practical application.
Requirements and Compatibility
PHP 8.x and a local test environment. Apply input validation, correct error handling and the requirements of any optional libraries.
The code focuses on the core concept. Production implementation may also need routes, validation, persistence, authorization or deployment tooling.
Example 1: Basic Behavior
Understand the primary operation and its inputs.
<?php
interface TextWriter { public function write(string $s): string; }
class PlainWriter implements TextWriter { public function write(string $s): string { return $s; } }
class UpperWriter implements TextWriter { public function __construct(private TextWriter $inner) {} public function write(string $s): string { return strtoupper($this->inner->write($s)); } }
echo (new UpperWriter(new PlainWriter()))->write('ok');
Example 2: Another Case
Check failure behavior or a different execution path.
<?php
interface Cost { public function cents(): int; }
class BaseCost implements Cost { public function cents(): int { return 100; } }
class TaxCost implements Cost { public function __construct(private Cost $base) {} public function cents(): int { return (int) round($this->base->cents() * 1.1); } }
echo (new TaxCost(new BaseCost()))->cents();
Practical Example: Putting It to Use
Apply the behavior in a small, controlled scenario.
<?php
interface LabelMaker { public function make(): string; }
class SimpleLabel implements LabelMaker { public function make(): string { return 'item'; } }
class PrefixLabel implements LabelMaker { public function __construct(private LabelMaker $inner) {} public function make(): string { return 'new-' . $this->inner->make(); } }
echo (new PrefixLabel(new SimpleLabel()))->make();
Important Behavior and Edge Cases
Preserve expected behavior and avoid surprising mutation or deeply nested wrappers.
Comparison with Related Functions or Approaches
| Option | What it means in practice |
|---|---|
| Applying the Decorator Pattern in PHP | A decorator wraps a dependency implementing the same contract to extend its behavior. |
| Related approach | A strategy swaps algorithms; an adapter changes incompatible interfaces. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Ignoring the important boundary for Applying the Decorator Pattern in PHP | Preserve expected behavior and avoid surprising mutation or deeply nested wrappers. |
| Assuming a related mechanism has the same behavior | A strategy swaps algorithms; an adapter changes incompatible interfaces. |
Key Takeaways
- A decorator wraps a dependency implementing the same contract to extend its behavior.
- Preserve expected behavior and avoid surprising mutation or deeply nested wrappers.
- A strategy swaps algorithms; an adapter changes incompatible interfaces.
Before adapting these examples, verify the return values, test the failure paths and confirm that your application meets its security and environment requirements.