El patrón decorador en PHP

El patrón decorador es simple. Nos permite agregar un nuevo comportamiento a las instancias de objetos sin afectar otras instancias de la misma clase. Básicamente actúa como un envoltorio de decoración alrededor de nuestro objeto. Podemos imaginar un caso de uso simple con una instancia de clase Logger, donde tenemos una clase simple de logger que nos gustaría decorar ocasionalmente, o envolver en un registrador de nivel de error, advertencia y aviso más específico.

El siguiente ejemplo demuestra una posible implementación del patrón decorador:

<?php
interface LoggerInterface
{
public function log($message);
}
class Logger implements LoggerInterface
{
public function log($message)
{
file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
}
}
abstract class LoggerDecorator implements LoggerInterface
{
protected $logger;
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
abstract public function log($message);
}
class ErrorLogger extends LoggerDecorator
{
public function log($message)
{
$this->logger->log('ErrorLogger: ' . $message);
}
}
class WarningLogger extends LoggerDecorator
{
public function log($message)
{
$this->logger->log('WarningLogger: ' . $message);
}
}
class NoticeLogger extends LoggerDecorator
{
public function log($message)
{
$this->logger->log('NoticeLogger: ' . $message);
}
}
// Client use
(new Logger())->log('Test Logger.');
(new ErrorLogger(new Logger()))->log('Test ErrorLogger.');
(new WarningLogger(new Logger()))->log('Test WarningLogger.');
(new NoticeLogger(new Logger()))->log('Test NoticeLogger.');

Aquí, comenzamos definiendo una interfaz LoggerInterface y una clase concreta de Logger que implementa esa interfaz. Luego creamos una clase abstracta de LoggerDecorator que también implementa LoggerInterface. LoggerDecorator realmente no implementa el método log() en sí mismo; lo define como abstracto para que las futuras clases secundarias lo implementen.
Finalmente, definimos las clases de decorador de error concreto, advertencia y aviso. Podemos ver sus métodos log () decorar la salida de acuerdo con sus roles. La salida resultante se muestra de la siguiente manera:

Test Logger.
ErrorLogger: Test ErrorLogger.
WarningLogger: Test WarningLogger.
NoticeLogger: Test NoticeLogger.

Comparte