interface Logger { log(string $msg): void; }
class FileLogger implements Logger { ... }
class TimestampLogger implements Logger {
public function __construct(private Logger $inner) {}
public function log(string $msg): void {
$this->inner->log(date('H:i:s') . ' ' . $msg);
}
}Декоратори комбінуються динамічно: new JsonLogger(new TimestampLogger(new FileLogger())). Спадкування вимагало б N² підкласів для кожної комбінації. Порушення Open/Closed при спадкуванні — звичне явище; декоратори його уникають.