Command Palette

Search for a command to run...

Chain of Responsibility: Pasando Solicitudes a Través de Handlers

Aprende a implementar el patrón Chain of Responsibility para pasar solicitudes a través de una cadena de handlers en JavaScript

Lectura: 14 min
Nivel: Intermedio

TL;DR - Resumen rápido

  • El Chain of Responsibility permite pasar solicitudes a través de una cadena de handlers
  • Cada handler decide si procesa la solicitud o la pasa al siguiente handler
  • Elimina el acoplamiento entre el emisor de la solicitud y sus receptores
  • Permite agregar o remover handlers dinámicamente sin modificar el código existente
  • Ideal para validaciones, logging, procesamiento de eventos y middleware

Introducción al Chain of Responsibility

El Chain of Responsibility es un patrón de diseño comportamental que te permite pasar solicitudes a lo largo de una cadena de handlers. Cada handler decide si procesa la solicitud o la pasa al siguiente handler en la cadena. Esto crea un flujo flexible donde la solicitud viaja hasta que encuentra un handler que la procesa o hasta que llega al final de la cadena.

En JavaScript, este patrón es especialmente útil para implementar sistemas de middleware, validaciones en cascada, procesamiento de eventos y cualquier situación donde necesites aplicar múltiples operaciones secuenciales sobre una solicitud. La cadena puede configurarse dinámicamente, permitiendo agregar o remover handlers sin modificar el código existente.

¿Cuándo usar Chain of Responsibility?

Usa este patrón cuando tengas múltiples objetos que pueden manejar una solicitud y no quieras especificar explícitamente cuál debe hacerlo. Es ideal para validaciones en cascada, sistemas de logging, procesamiento de eventos HTTP, o cualquier situación donde necesites aplicar múltiples filtros o transformaciones a una solicitud.

Implementación Básica

La implementación básica del Chain of Responsibility requiere una clase base para los handlers que define la estructura común, y clases concretas que implementan la lógica específica de cada handler. Cada handler tiene una referencia al siguiente handler en la cadena, creando una estructura enlazada que permite que la solicitud viaje a través de todos los handlers.

Handlers en la Cadena

Cada handler en la cadena implementa la lógica para procesar solicitudes específicas. Si el handler puede procesar la solicitud, lo hace y termina la cadena. Si no puede procesarla, la pasa al siguiente handler. Esto permite que cada handler se especialice en un tipo específico de solicitud o condición.

chain-handlers.js
Loading code...

Este ejemplo muestra cómo implementar handlers especializados para diferentes tipos de solicitudes. Cada handler verifica si puede procesar la solicitud y, si no puede, la pasa al siguiente handler en la cadena. Esto permite que la solicitud viaje a través de múltiples handlers hasta que uno la procesa.

Encadenamiento de Handlers

La clave del Chain of Responsibility es que cada handler conoce solo al siguiente handler en la cadena, creando un acoplamiento mínimo. Esto permite agregar o remover handlers fácilmente sin afectar el resto de la cadena, haciendo el sistema más flexible y mantenible.

Pasando la Solicitud

El proceso de pasar la solicitud a través de la cadena es fundamental para el patrón. Cada handler decide si procesa la solicitud o la pasa al siguiente. Cuando un handler procesa la solicitud, puede terminar la cadena o continuar pasándola para que otros handlers también la procesen.

chain-pasando.js
Loading code...

Este ejemplo muestra cómo la solicitud viaja a través de la cadena hasta que un handler la procesa. La solicitud comienza en el primer handler y se pasa sucesivamente hasta que encuentra un handler que puede procesarla o llega al final de la cadena.

Orden de la Cadena

El orden de los handlers en la cadena es crucial para el comportamiento del patrón. Los handlers se ejecutan en el orden en que se agregan a la cadena, y este orden determina qué handler procesará primero la solicitud. Es importante configurar la cadena en el orden correcto según las reglas de negocio.

chain-orden.js
Loading code...

Este ejemplo muestra cómo el orden de los handlers afecta el procesamiento de solicitudes. Los handlers más específicos o restrictivos deben ir primero en la cadena, mientras que los handlers más generales deben ir al final. Esto asegura que las solicitudes se procesen de manera correcta y eficiente.

Casos de Uso

El Chain of Responsibility tiene múltiples aplicaciones prácticas en desarrollo de software. Comprender estos casos de uso te ayudará a identificar cuándo es apropiado implementar este patrón en tus proyectos.

  • <strong>Validaciones en cascada:</strong> Validar datos a través de múltiples reglas secuenciales.
  • <strong>Sistemas de logging:</strong> Pasar mensajes de log a través de múltiples handlers (consola, archivo, remoto).
  • <strong>Middleware HTTP:</strong> Procesar solicitudes HTTP a través de una cadena de middleware.
  • <strong>Procesamiento de eventos:</strong> Pasar eventos a través de múltiples listeners.
  • <strong>Autenticación y autorización:</strong> Verificar permisos a través de múltiples niveles.
  • <strong>Filtros de datos:</strong> Aplicar múltiples filtros a un conjunto de datos.

Errores Comunes

Al implementar el Chain of Responsibility, es fácil cometer errores que pueden causar comportamiento inesperado o problemas de rendimiento. Aquí analizamos los errores más frecuentes y cómo evitarlos.

  • <strong>Ciclos infinitos:</strong> Evita que un handler pase la solicitud a un handler anterior en la cadena
  • <strong>Olvidar pasar solicitud:</strong> Siempre pasa la solicitud al siguiente cuando no puedas procesarla
  • <strong>Cadena vacía:</strong> Verifica que la cadena tenga handlers antes de procesar solicitudes
  • <strong>Orden incorrecto:</strong> Coloca handlers específicos antes que los genéricos
  • <strong>No documentar la cadena:</strong> Documenta el orden y propósito de cada handler

Ciclos Infinitos en la Cadena

Un error común es crear ciclos infinitos en la cadena, donde un handler pasa la solicitud a otro handler que eventualmente la devuelve al primero. Esto causa que la solicitud nunca termine de procesarse y puede causar un desbordamiento de pila.

error-ciclo-infinito.js
Loading code...

Este ejemplo muestra cómo crear accidentalmente un ciclo infinito en la cadena. El handler A pasa la solicitud al handler B, y el handler B la pasa de vuelta al handler A, creando un ciclo que nunca termina. Para evitar esto, asegúrate de que la cadena sea lineal y que ningún handler pase la solicitud a un handler anterior en la cadena.

Olvidar Pasar la Solicitud

Otro error común es olvidar pasar la solicitud al siguiente handler cuando el handler actual no puede procesarla. Esto hace que la solicitud se detenga prematuramente en la cadena y no sea procesada por handlers que podrían manejarla.

error-olvido-pasar.js
Loading code...

Este ejemplo muestra cómo olvidar pasar la solicitud puede causar que handlers válidos no la procesen. Cuando un handler no puede procesar la solicitud, siempre debe pasarla al siguiente handler en la cadena, a menos que sea el último handler.

Advertencia de Terminación Prematura

Siempre pasa la solicitud al siguiente handler cuando el handler actual no puede procesarla. Olvidar esto puede causar que solicitudes válidas no sean procesadas, especialmente cuando agregas nuevos handlers a la cadena en el futuro.

Cadena Vacía o Sin Handlers

Es posible que la cadena esté vacía o que no tenga handlers configurados. En este caso, las solicitudes no se procesarán y se perderán. Es importante manejar este caso de borde y proporcionar un comportamiento predeterminado o lanzar un error apropiado.

error-cadena-vacia.js
Loading code...

Este ejemplo muestra cómo manejar el caso de una cadena vacía. Cuando no hay handlers en la cadena, es importante proporcionar un comportamiento predeterminado o lanzar un error que indique que la solicitud no pudo ser procesada.

Resumen: Chain of Responsibility

Conceptos principales:

  • El Chain of Responsibility pasa solicitudes a través de una cadena de handlers
  • Cada handler decide si procesa la solicitud o la pasa al siguiente
  • Elimina el acoplamiento entre el emisor y los receptores de la solicitud
  • La cadena puede configurarse dinámicamente agregando o removiendo handlers
  • El orden es crucial y la solicitud viaja hasta procesarse o llegar al final

Mejores prácticas:

  • Define claramente qué tipos de solicitudes puede procesar cada handler
  • Configura la cadena en el orden correcto según las reglas de negocio
  • Siempre pasa la solicitud al siguiente handler cuando no puedas procesarla
  • Evita ciclos infinitos asegurando que la cadena sea lineal
  • Maneja el caso de cadena vacía con un comportamiento predeterminado
  • Usa este patrón para validaciones en cascada, middleware y procesamiento de eventos