Observer pattern: filtros reactivos en JavaScript

Clase 8 de 24Curso de Manipulación Avanzada de Datos con JavaScript

Resumen

Convierte filtros manuales en una experiencia fluida: con programación reactiva en JavaScript usando el observer pattern lograrás que la interfaz se actualice automáticamente cuando cambie el estado de los filtros. Este enfoque declarativo, más fácil de mantener, evita el código espagueti y mejora la claridad del flujo de datos.

¿Por qué cambiar a programación reactiva?

Pasar de una forma “hiperactiva” (imperativa y manual) a una declarativa y reactiva reduce complejidad. En lugar de llamar funciones dentro de cada clic o evento, se observan cambios en el estado de los filtros y la UI se renderiza cuando corresponde.

¿Qué problema resuelve en los filtros?

  • Actualiza el render cuando cambian los filtros, sin llamadas manuales en cada evento.
  • Disminuye el acoplamiento: los interesados se suscriben y reciben cambios.
  • Mejora la mantenibilidad con un patrón probado.
  • Facilita pruebas, lectura y evolución del código.

¿Qué recursos se recomiendan para aprender patrones?

  • patterns.net: referencia clara de patrones, con ejemplos y video explicativo.
  • Versión en ebook o PDF para repasar sin conexión.
  • Paths punto dev: otros patrones, videos y material didáctico para profundizar.

¿Cómo implementar el observer pattern paso a paso?

El patrón define un sujeto observable que mantiene una lista de funciones observadoras. Con tres métodos básicos —subscribe, unsubscribe y notify— se logra programación reactiva sin ejecutar funciones de forma explícita en cada interacción.

¿Qué estructura mínima necesita?

  • Un array privado de observadores.
  • Métodos: subscribe para agregar funciones, unsubscribe para quitarlas, notify para notificar cambios.
  • Inmutabilidad al remover: usar filter en vez de un split para no mutar el array.
  • Un estado centralizado de filtros: frecuencia, status, mínimo de seguidos y búsqueda en texto.
  • Actualizaciones declarativas: cuando cambia el estado, se notifica a los suscriptores.
// Implementación base del observer pattern aplicada a un estado de filtros class FilterState { #observers = []; // array privado de observadores constructor() { this.filters = { frequency: '', status: '', minStreak: 0, search: '' }; } // lectura del estado (no muta el original) getState() { return { ...this.filters }; } // suscripción subscribe(observerFn) { this.#observers.push(observerFn); } // desuscripción sin mutar el array original unsubscribe(observerFn) { this.#observers = this.#observers.filter(fn => fn !== observerFn); } // notificación a todos los interesados notify() { const state = this.getState(); this.#observers.forEach(fn => fn(state)); } // actualizar un filtro específico set(name, value) { this.filters = { ...this.filters, [name]: value }; // "split" operator según lo explicado this.notify(); } // actualizar múltiples filtros a la vez setAll(partial) { this.filters = { ...this.filters, ...partial }; this.notify(); } // reset al estado inicial reset() { this.filters = { frequency: '', status: '', minStreak: 0, search: '' }; this.notify(); } }

¿Cómo se usa en la interfaz?

  • Se suscribe una función de render para reaccionar a cambios.
  • Los eventos solo actualizan el estado; la UI se actualiza al ser notificada.
const filterState = new FilterState(); // función que renderiza según el estado actual function render(state) { // ejemplo: aplicar .filter al array base y pintar resultados // const result = data.filter(...usando state...); // updateUI(result); } // suscripción reactiva filterState.subscribe(render); // cambios desde eventos (click, change, input) // filterState.set('status', 'active'); // dispara render automáticamente // filterState.setAll({ search: 'texto', minStreak: 3 });

¿Qué decisiones clave destacar?

  • En notify puedes enviar la data explícita o leerla del estado central: aquí se pasa el estado de filtros.
  • Se siguen usando métodos clásicos de arrays como push y filter, aplicados dentro de un patrón más avanzado.
  • Mantener la inmutabilidad evita efectos colaterales y facilita el razonamiento del flujo.

¿Dónde aplica y qué beneficios ofrece?

Este patrón es muy usado en programación reactiva, especialmente en front end y en flujos de datos en tiempo real: streaming, chats y cualquier escenario real time. Se mencionan dos puntos relevantes: existe un constructor Observable de forma nativa en ESMA Script y la librería RxJS lleva la reactividad a otro nivel; incluso grandes plataformas como Netflix la emplean para procesar streaming en tiempo real en backend y navegador.

  • Menos código imperativo y menos dependencias entre componentes.
  • UI siempre consistente con el estado de filtros.
  • Base sólida para ampliar lógica de negocio sin reescribir eventos.
  • Patrón estándar: observable, subscribe, unsubscribe, notify.

¿Te gustaría compartir cómo enviarías los cambios de filtros desde tus eventos actuales y qué parte del render te gustaría desacoplar primero?