LARAVEL OBSERVER VS LISTENER: ¿CUÁNDO USAR CADA UNO?

En Laravel, tanto los Observers como los Listeners son herramientas poderosas para implementar lógica reactiva. Sin embargo, tienen propósitos diferentes y usar uno en lugar del otro puede generar código difícil de mantener o arquitecturas confusas.

¿Qué es un Observer?

Un Observer está diseñado para reaccionar a los cambios en el ciclo de vida de un solo modelo Eloquent. Se activa automáticamente cuando ocurre un evento en el modelo: "created", "updated", "deleted", "saved", "restored", etc. Tanto los Observers como los Listeners son excelentes, pero tienen un propósito distinto. Usar la herramienta correcta en el momento adecuado es lo que diferencia un código mantenible y escalable de uno que se vuelve una bola de nieve.

Casos de uso

  • Crear logs de auditoría
  • Invalidar caché relacionado con el modelo
  • Sincronizar datos relacionados (ej. actualizar contadores)
  • Mantener lógica estrechamente relacionada con el modelo

Ejemplo

// app/Observers/UserObserver.php
class UserObserver
{
    public function created(User $user): void
    {
        AuditLog::create([
            'user_id' => $user->id,
            'event'   => 'created',
        ]);
    }

    public function updated(User $user): void
    {
        // Invalidar caché, recalcular algo, etc.
    }
}
Se registra en el "AppServiceProvider" o mediante "User::observe(UserObserver::class);". Está fuertemente acoplado al modelo. Ideal cuando la lógica es intrínseca al modelo.

¿Qué es un Listener?

Un Listener reacciona a Eventos de dominio o eventos de negocio que el programador despacha. Es parte del patrón Event-Driven Architecture y es mucho más flexible para lógica de aplicación.

Casos de uso

  • Enviar emails de bienvenida
  • Notificaciones push
  • Integraciones con terceros (Slack, Stripe Webhooks, etc.)
  • Tracking de analytics
  • Workflows asíncronos
  • Cualquier acción que represente un evento de negocio

Ejemplo

// Evento
event(new UserRegistered($user));

// Listener
class SendWelcomeEmail implements ShouldQueue
{
    public function handle(UserRegistered $event): void
    {
        Mail::to($event->user->email)
            ->send(new WelcomeEmail($event->user));
    }
}

Mejores Prácticas

  • Mantener los Observers solo con lógica relacionada directamente con el modelo.
  • Usar Listeners para tareas pesadas como correos, notificaciones, integraciones externas.
  • Aprovechar Queued Listeners e implementar ShouldQueue siempre que sea posible.
  • Nombrar bien los evento como "UserRegistered", "OrderShipped", "PaymentFailed", etc.
  • Usar Event Discovery ya que reduce la configuración manual.
  • Type Safety con tipado fuerte en eventos y listener.

Si la lógica está atada al modelo → Observer.

Si la lógica representa una acción de negocio → Evento + Listener.