Patrón de cadena de responsabilidad
El patrón de cadena de responsabilidad (Chain of Responsibility Pattern) crea una cadena de objetos receptores para la solicitud. Este patrón desacopla al emisor y al receptor de la solicitud según el tipo de solicitud. Este tipo de patrón de diseño pertenece a los patrones de comportamiento.
El patrón de cadena de responsabilidad conecta múltiples manejadores (objetos de procesamiento) en una estructura de cadena, haciendo que la solicitud se transmita a lo largo de la cadena hasta que un manejador la procese.
El patrón de cadena de responsabilidad permite que múltiples objetos tengan la oportunidad de procesar la solicitud, evitando así el acoplamiento entre el emisor y el receptor de la solicitud. Estos objetos se conectan en una cadena y la solicitud se transmite a lo largo de la cadena.
Introducción
Intención
Permite transmitir la solicitud a lo largo de la cadena de manejadores hasta que la solicitud sea procesada.
Problemas principales que resuelve
- Desacoplar al emisor y al receptor de la solicitud, de modo que múltiples objetos tengan la posibilidad de recibir la solicitud y el emisor no necesite saber qué objeto la manejará.
Escenarios de uso
- Cuando hay múltiples objetos que pueden procesar la solicitud y cuál de ellos la procesa se decide en tiempo de ejecución.
- Cuando se necesita enviar una solicitud a uno de varios objetos sin querer especificar explícitamente el receptor.
Forma de implementación
- Definir la interfaz del manejador: Todos los manejadores deben implementar la misma interfaz.
- Crear manejadores concretos: Clases concretas que implementan la interfaz, contienen la lógica de procesamiento de la solicitud y una referencia al siguiente manejador en la cadena.
Código clave
- Interfaz Handler: Define un método para procesar la solicitud.
- Clase ConcreteHandler: Implementa la interfaz Handler, contiene la lógica de procesamiento de la solicitud y una referencia al siguiente manejador.
Ejemplos de aplicación
- Pasar la flor al son del tambor: Comportamiento de pasar en el juego hasta que la música se detenga.
- Propagación de eventos: En JavaScript, el evento comienza desde el elemento más específico y se propaga hacia arriba nivel por nivel.
- Servidor web: Como Apache Tomcat que maneja la codificación de caracteres, los interceptores de Struts2 y los filtros de Servlet.
Ventajas
- Reducción del acoplamiento: Desacopla al emisor y al receptor.
- Simplificación de objetos: Los objetos no necesitan conocer la estructura de la cadena.
- Flexibilidad: Al cambiar los miembros o el orden de la cadena, se pueden agregar o eliminar responsabilidades dinámicamente.
- Fácil de extender: Es muy conveniente añadir nuevas clases de procesamiento de solicitudes.
Desventajas
- Solicitud no procesada: No se garantiza que la solicitud sea recibida por algún manejador de la cadena.
- Impacto en el rendimiento: Puede afectar el rendimiento del sistema, es difícil de depurar y puede provocar llamadas cíclicas.
- Difícil de observar: Las características en tiempo de ejecución no son evidentes, lo que puede dificultar la depuración.
Recomendaciones de uso
- Al procesar solicitudes, si hay varios manejadores potenciales, considere usar el patrón de cadena de responsabilidad.
- Asegúrese de que cada manejador de la cadena sepa claramente cómo transmitir la solicitud al siguiente eslabón de la cadena.
Precauciones
- En el desarrollo Java Web, el patrón de cadena de responsabilidad tiene amplias aplicaciones, como cadenas de filtros, interceptores, etc.
Estructura
Involucra principalmente los siguientes roles clave:
Manejador abstracto (Handler):
- Define una interfaz para procesar solicitudes, que generalmente incluye un método para procesar la solicitud (como
handleRequest) y una referencia al siguiente manejador (sucesor).
- Define una interfaz para procesar solicitudes, que generalmente incluye un método para procesar la solicitud (como
Manejador concreto (ConcreteHandler):
- Implementa la interfaz del manejador abstracto y es responsable de procesar la solicitud. Si puede procesarla, la maneja directamente; de lo contrario, la transmite al siguiente manejador.
Cliente (Client):
- Crea los objetos manejadores y los conecta en una cadena de responsabilidad. Normalmente, el cliente solo necesita enviar la solicitud al primer manejador de la cadena, sin preocuparse por el proceso específico de manejo de la solicitud.
Implementación
Creamos la clase abstractaAbstractLogger, con niveles detallados de registro. Luego creamos tres tipos de registradores, todos extiendenAbstractLogger. Cada registrador verifica si el nivel del mensaje es de su propio nivel; si lo es, lo imprime en consecuencia; de lo contrario, no lo imprime y pasa el mensaje al siguiente registrador.
Paso 1
Crear la clase registradora abstracta.
AbstractLogger.java
Paso 2
Crear clases concretas que extienden la clase registradora.
ConsoleLogger.java
ErrorLogger.java
FileLogger.java
Paso 3
Crear diferentes tipos de registradores. Asignarles diferentes niveles de error y configurar el siguiente registrador en cada uno. El siguiente registrador en cada registrador representa una parte de la cadena.
ChainPatternDemo.java
Paso 4
Ejecutar el programa y mostrar el resultado:
Standard Console::Logger: This is an information. File::Logger: This is a debug level information. Standard Console::Logger: This is a debug level information. Error Console::Logger: This is an error information. File::Logger: This is an error information. Standard Console::Logger: This is an error information.Otras extensiones