Event Bus y el patrón Observer en C++: implementación y ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Event Bus y el patrón Observer en C++: de la teoría a la práctica



En el desarrollo moderno de software en C++, el acoplamiento débil de componentes juega un papel importante. El patrón Observer (Observador) y su evolución — Event Bus (Bus de eventos) — proporcionan un mecanismo elegante para organizar la interacción entre objetos sin crear dependencias rígidas. En este artículo, analizaremos en detalle cómo implementar estos patrones en C++, consideraremos sus ventajas y limitaciones, y proporcionaremos ejemplos prácticos de código.



Patrón Observer: implementación clásica



El patrón Observer define una relación de "uno a muchos" entre objetos: cuando un objeto (sujeto) cambia su estado, todos los objetos que dependen de él (observadores) son notificados automáticamente. En C++, la implementación clásica se ve de la siguiente manera:



#include <iostream>#include <vector>#include <memory>#include <algorithm>

// Interfaz del observadorclass IObserver {public: virtual ~IObserver() = default; virtual void update(const std::string& message) = 0;};

// Observador concretoclass ConcreteObserver : public IObserver {private: std::string name;public: explicit ConcreteObserver(const std::string& n) : name(n) {} void update(const std::string& message) override { std::cout << "[" << name << "] Recibido: " << message << std::endl; }};

// Sujeto (objeto observado)class Subject {private: std::vector<std::shared_ptr<IObserver>> observers; std::string state;public: void attach(std::shared_ptr<IObserver> observer) { observers.push_back(observer); } void detach(std::shared_ptr<IObserver> observer) { observers.erase( std::remove(observers.begin(), observers.end(), observer), observers.end() ); } void notify() { for (auto& observer : observers) { observer->update(state); } } void setState(const std::string& newState) { state = newState; notify(); }};

int main() { Subject subject; auto obs1 = std::make_shared<ConcreteObserver>("Observador 1"); auto obs2 = std::make_shared<ConcreteObserver>("Observador 2"); subject.attach(obs1); subject.attach(obs2); subject.setState("¡Evento #1 ocurrió!"); subject.detach(obs1); subject.setState("Evento #2 sin el primer observador"); return 0;}


Event Bus: bus de eventos centralizado



Event Bus amplía la idea de Observer, proporcionando un mecanismo centralizado de intercambio de mensajes. En lugar de que cada sujeto almacene una lista de observadores, todas las suscripciones y publicaciones pasan a través de un bus único. Esto permite:

  • Reducir el acoplamiento — los emisores y receptores no saben nada el uno del otro.
  • Simplificar la escalabilidad — se añaden nuevos tipos de eventos sin modificar el código existente.
  • Proporcionar flexibilidad — se pueden añadir y eliminar suscriptores en tiempo de ejecución.


Ejemplo de implementación de Event Bus en C++ usando plantillas y std::function:



#include <iostream>#include <unordered_map>#include <functional>#include <any>#include <typeindex>#include <vector>#include <memory>

// Clase base para eventosstruct Event { virtual ~Event() = default;};

// Evento concretostruct UserLoginEvent : public Event { std::string username; explicit UserLoginEvent(std::string name) : username(std::move(name)) {}};

// Clase Event Busclass EventBus {private: std::unordered_map<std::type_index, std::vector<std::function<void(const std::any&)>>> hand

Recommendations