Definición: permite que múltiples objetos tengan la oportunidad de procesar la solicitud, evitando así la relación de acoplamiento entre el remitente y el receptor de la solicitud. Conecte estos objetos en una cadena y pase la solicitud a lo largo de la cadena hasta que un objeto la procese.
Tipo: Patrón de comportamiento
Diagrama de clases:
Veamos primero un código:
Public void test (int i, solicitud de solicitud) {if (i == 1) {handler1.Response (solicitud); } else if (i == 2) {handler2.Response (solicitud); } else if (i == 3) {Handler3.Response (solicitud); } else if (i == 4) {Handler4.Response (solicitud); } else {Handler5.Response (solicitud); }} La lógica comercial del código es la siguiente: el método tiene dos parámetros: el entero I y una solicitud de solicitud. De acuerdo con el valor de I, quién manejará la solicitud, si i == 1, Handler2 la manejará, si I == 2, será manejado por Handler2, y así sucesivamente. En la programación, este tipo de método de procesamiento comercial es muy común. Todas las clases de las solicitudes de proceso incluyen si ... de lo contrario ... declaraciones de juicio condicional conectadas a una cadena de responsabilidad para procesar la solicitud. Creo que todos lo usan a menudo. Las ventajas de este método son que es muy intuitiva, simple y clara y relativamente fácil de mantener, pero este método también tiene varios dolores de cabeza:
Código hinchado: en las aplicaciones reales, las condiciones del juicio generalmente no son tan simples de determinar si es 1 o 2. Puede requerir cálculos complejos, tal vez consultar la base de datos, etc. Esto tendrá mucho código adicional. Si hay muchas condiciones de juicio, entonces esto si ... de lo contrario ... la declaración es básicamente imposible de leer.
Grado de acoplamiento alto: si queremos continuar agregando clases que procesen solicitudes, debemos continuar agregando más si el juicio se condiciones; Además, el orden de esta condición también se escribe a los muertos. Si queremos cambiar el pedido, solo podemos modificar esta declaración de condición.
Como ya hemos entendido las deficiencias, necesitamos encontrar una manera de resolverlas. La lógica comercial de este escenario es muy simple: si se cumple la condición 1, Handler1 la procesará, y si no se cumple, se transmitirá; Si se cumple la condición 2, Handler2 la procesará, y si no se cumple, se transmitirá, y así sucesivamente hasta el final de la condición. De hecho, el método de mejora también es muy simple, que es poner la parte de las condiciones del juicio en la clase de procesamiento. Este es el principio del modelo de conexión de responsabilidad.
La estructura del modelo de empresa de responsabilidad
El diagrama de clase del patrón conectado a la responsabilidad es muy simple, consiste en una clase procesada abstracta y su conjunto de clases de implementación:
Clase de procesamiento abstracto: la clase de procesamiento abstracto incluye principalmente un nextandler variable miembro que apunta a la siguiente clase de procesamiento y una requería de mano de método que maneja la solicitud. La idea principal del método de requisito de manos es que si se cumplen las condiciones de procesamiento, esta clase de procesamiento será procesada, de lo contrario, Nexthandler lo procesará.
Clase de procesamiento específica: la clase de procesamiento específica implementa principalmente la lógica de procesamiento específica y las condiciones aplicables para el procesamiento.
Ejemplo
El modelo de cadena de responsabilidad tiene dos roles:
Rol de controlador de abstracto: define una interfaz solicitada. Si es necesario, puede definir un método para establecer y devolver la referencia al siguiente objeto de inicio.
Rol de ConcreteHandler: si se puede procesar, procese la solicitud. Si no se puede procesar, pase la solicitud a la próxima casa y deje que la próxima casa lo maneje. Es decir, maneja las solicitudes que puede manejar y puede acceder a su próximo hogar.
El código de prueba para el patrón anterior es el siguiente:
paquete chaineofResp;/***Descripción: rol de procesamiento abstracto*/controlador de clases abstracto público {Sucesor de controlador protegido; / ***Descripción: Método de procesamiento*/ public abstract void handlerRequest (condición de cadena); Public Handler GetSuccessor () {Sucesor de retorno; } public void setSuccessor (Sucesor de controlador) {this.successor = sucesor; }} Paquete ChainOfResp;/***Descripción: Manejo detallado de roles*/public class ConcreteHandler1 extiende el manejador {@Override public void HandlerRequest (condición de cadena) {// Si es su propia responsabilidad, lo manejará tú mismo y será responsable de pasarlo al siguiente hogar if (condicion.equals ("ConcreteHandler1")) {System.out.Println ("" "Concrinler1). devolver ; } else {System.out.println ("ConcreteHandler1 pasado"); getSuccessor (). HandlerRequest (condición); }}} Paquete ChainOfResp;/***Descripción: Manejo detallado de roles*/public class ConcreteHandler2 extiende el manejador {@Override public void HandlerRequest (condición de cadena) {// Si es su propia responsabilidad, lo manejará y será responsable de pasarlo al siguiente hogar If (condición. Equals ("ConcreteHandler2")) {System.out.Println ("" ConcRoN2. devolver ; } else {System.out.println ("ConcreteHandler2 pasado"); getSuccessor (). HandlerRequest (condición); }}} Paquete ChainOfResp;/*** Descripción: Rol de procesamiento detallado*/public class ConcreteHandlern extiende el controlador {/*** Aquí se supone que n es el último nodo de la cadena que debe procesarse* en situaciones reales, un anillo o un árbol puede aparecer,* Este no es necesariamente el último nodo. * */ @Override public void HandlerRequest (condición de cadena) {System.out.println ("ConcreteHandlern manejado"); }} Paquete ChainofResp;/***Descripción: Test Class*/public class Client {/***Descripción:*/public static void main (string [] args) {Handler Handler1 = new ConcreteHandler1 (); Handler Handler2 = new ConcreteHandler2 (); Handler Handlern = new ConcreteHandlern (); // cadena Handler1.SetSuccessor (Handler2); Handler2.SetSuccessor (manual); // Suponga que esta solicitud es responsabilidad de ConcreteHandler2 Handler1.HandlerRequest ("ConcreteHandler2"); }}
Para dar este ejemplo, en el taller de producción de una fábrica de juguetes, la línea de ensamblaje es una cadena de responsabilidad. Si un avión de juguete tiene un ensamblador de caparazón, ensamblador de motor, ensamblador de hélice y empacador de modelos. Cuando la aeronave fluye a quien sea que fluya el objeto, será responsable de instalar la parte de la que es responsable. Después de instalar esta parte, fluirá al siguiente paso y sabrá que todos los entornos están completados. Esta es una cadena de responsabilidad que se genera. También hay una cadena de inspección de calidad, que se divide en múltiples piezas, inspección de concha, inspección del motor, inspección de la hélice e inspección de empaquetado. Cuando el producto se deja al inspector para probar la pieza de la que es responsable, si hay algún problema, se eliminará directamente. Si no hay problema, se pasará al próximo inspector hasta que se completen todas las pruebas. Estas dos son cadenas de responsabilidad, pero la diferencia es que todos procesarán la cadena de responsabilidad y procesan parte de ella; Mientras que después del juicio, la cadena de responsabilidad por la inspección de calidad será procesada o no procesada. Estas son las dos categorías de cadenas de responsabilidad. Este último se llama cadenas de responsabilidad pura, y la primera se llama cadenas de responsabilidad impuradores. Las cadenas de responsabilidad pura rara vez existen en aplicaciones prácticas. El común son las cadenas de responsabilidad impuradores. El modelo anterior simula cadenas de responsabilidad pura para manejar.
Pros y contras del modelo de cadena de responsabilidad
En comparación con si ... de lo contrario ..., el patrón de cadena de responsabilidad tiene una capacidad de acoplamiento más baja porque distribuye los juicios condicionales en varias clases de procesamiento, y el orden de procesamiento de prioridad de estas clases de procesamiento se puede establecer a voluntad. El modelo de cadena de responsabilidad también tiene sus desventajas, que es lo mismo que la declaración if ... else ..., es decir, antes de encontrar la clase de procesamiento correcta, todas las condiciones de juicio deben ejecutarse. Cuando la cadena de responsabilidad es relativamente larga, el problema de rendimiento es más grave.
Escenarios aplicables para el modelo de cadena de responsabilidad
Al igual que el ejemplo inicial, si se siente abrumado al usar la declaración if ... de lo contrario ... para organizar una cadena de responsabilidad y el código se ve mal, puede usar la cadena de responsabilidad para refactorizarla.
Resumir
El modelo de cadena de responsabilidad es en realidad una versión flexible de la declaración if ... else ... Pone estas condiciones de juicio en cada clase de procesamiento. La ventaja de esto es que es más flexible, pero también trae riesgos. Por ejemplo, al establecer la relación entre la clase de procesamiento antes y después de la clase de procesamiento, debe tener mucho cuidado de juzgar la relación entre la lógica condicional antes y después de la clase de procesamiento, y tener cuidado de no tener referencias circulares en la cadena.