StructuralPHPverifiedVerified

Decorator Pattern in PHP

Attaches additional responsibilities to an object dynamically by wrapping it in decorator objects that share the same interface.

How to Implement the Decorator Pattern in PHP

1Step 1: Define the component interface

interface DataSource
{
    public function writeData(string $data): void;
    public function readData(): string;
}

2Step 2: Implement the base concrete component

class FileDataSource implements DataSource
{
    private string $data = '';

    public function writeData(string $data): void { $this->data = $data; }
    public function readData(): string { return $this->data; }
}

3Step 3: Implement the base decorator

abstract class DataSourceDecorator implements DataSource
{
    public function __construct(protected DataSource $wrapped) {}

    public function writeData(string $data): void { $this->wrapped->writeData($data); }
    public function readData(): string { return $this->wrapped->readData(); }
}

4Step 4: Implement concrete decorators

class EncryptionDecorator extends DataSourceDecorator
{
    public function writeData(string $data): void
    {
        $encrypted = base64_encode($data); // Simple simulation
        parent::writeData($encrypted);
    }

    public function readData(): string
    {
        $data = parent::readData();
        return base64_decode($data);
    }
}

class CompressionDecorator extends DataSourceDecorator
{
    public function writeData(string $data): void
    {
        $compressed = gzcompress($data);
        parent::writeData($compressed);
    }

    public function readData(): string
    {
        $data = parent::readData();
        return gzuncompress($data);
    }
}

// Usage — stack decorators
$source = new CompressionDecorator(
    new EncryptionDecorator(
        new FileDataSource()
    )
);
$source->writeData('Hello World');
echo $source->readData(); // "Hello World"

Decorator Pattern Architecture

hourglass_empty

Rendering diagram...

lightbulb

Decorator Pattern in the Real World

Think of adding espresso shots and syrups to a coffee order. A plain coffee is the base component. Each addition—an espresso shot, vanilla syrup, oat milk—is a decorator that wraps the previous cup, adding its own cost and flavor. You can combine them in any order without the café needing a separate menu item for every combination.