Event Bus e padrão Observer em PHP
No desenvolvimento moderno de aplicações web em PHP, surge frequentemente a necessidade de reagir de forma flexível a vários eventos: envio de e-mail após o registro, registro de ações do usuário, atualização de cache ao alterar dados. Para esses fins, o padrão Observer e sua extensão — Event Bus (barramento de eventos) — são ideais.
Padrão Observer: fundamentos
O padrão Observer (Observador) é um padrão de design comportamental que cria um mecanismo de inscrição, permitindo que objetos acompanhem e reajam a eventos que ocorrem em outros objetos. Componentes principais:
- Subject (Sujeito) — objeto que gera eventos
- Observer (Observador) — objeto que reage a eventos
- Event (Evento) — informações sobre a ação ocorrida
Event Bus: evolução do Observer
Event Bus é um barramento centralizado que gerencia todos os eventos na aplicação. Diferente do Observer clássico, onde a inscrição está rigidamente vinculada ao sujeito, o Event Bus oferece:
- Baixo acoplamento entre remetentes e destinatários
- Possibilidade de adicionar/remover manipuladores durante a execução
- Acesso global ao barramento de qualquer parte da aplicação
- Testes e depuração simplificados
Exemplo de implementação do Event Bus em PHP
Vamos criar uma implementação simples, porém funcional, do Event Bus, compatível com PSR-14 (Event Dispatcher).
<?php// Interface do eventointerface EventInterface{ public function getName(): string;}
// Evento baseclass UserRegisteredEvent implements EventInterface{ public function __construct( private string $email, private string $username ) {}
public function getName(): string { return 'user.registered'; }
public function getEmail(): string { return $this->email; }
public function getUsername(): string { return $this->username; }}
// Interface do manipuladorinterface EventHandlerInterface{ public function handle(EventInterface $event): void;}
// Event Busclass EventBus{ private array $listeners = [];
public function addListener(string $eventName, EventHandlerInterface $handler): void { $this->listeners[$eventName][] = $handler; }
public function removeListener(string $eventName, EventHandlerInterface $handler): void { if (!isset($this->listeners[$eventName])) { return; }
$this->listeners[$eventName] = array_filter( $this->listeners[$eventName], fn($h) => $h !== $handler ); }
public function dispatch(EventInterface $event): void { $eventName = $event->getName();
if (!isset($this->listeners[$eventName])) { return; }
foreach ($this->listeners[$eventName] as $handler) { $handler->handle($event); } }}?>Uso prático
Agora vamos criar manipuladores e demonstrar o funcionamento do barramento:
<?php// Manipulador de envio de e-mailclass SendWelcomeEmailHandler implements EventHandlerInterface{ public function handle(EventInterface $event): void { if (!$event instanceof UserRegisteredEvent) { return; }
echo "Enviando e-mail de boas-vindas para {$event->getEmail()}"; // mail($event->getEmail(), 'Bem-vindo!', '...'); }}
// Manipulador de registroclass LogUserRegistrationHandler implements EventHandlerInterface{ public function handle(EventInterface $event): void { if (!$event instanceof UserRegisteredEvent) { return; } Também na biblioteca
Processamento JSON em JavaScript (Node.js): guia completo
Serde para Rust: guia completo com exemplos
Trabalhando com arquivos ZIP em Node.js: bibliotecas archiver e adm-zip
Processamento JSON em Swift: Codable, JSONSerialization e exemplos práticos