Introducción
El Patrón de Cadena de Responsabilidad 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 esta cadena hasta que un objeto la maneje.
Ejemplo
El modelo de cadena de responsabilidad incluye los siguientes roles:
Handler
: Procesador abstracto. Defina una interfaz para procesar solicitudes. Si es necesario, la interfaz puede definir un método para establecer y devolver una referencia a la siguiente casa. Esta función generalmente se implementa mediante una clase abstracta de Java o una interfaz de Java.ConcreteHandler
: El procesador específico. Después de recibir la solicitud, el procesador específico puede optar por procesar la solicitud o pasar la solicitud a la siguiente parte. Dado que el procesador específico tiene una referencia a la siguiente casa, el procesador específico puede visitar la siguiente casa si es necesario.Client
: Clase de cliente
A continuación, tomamos como ejemplo una simple solicitud de permiso. Suponiendo que un día de licencia, el gerente del proyecto puede manejarlo, los tres días y así sucesivamente son manejados por el director del proyecto, dentro de los siete días lo maneja el jefe, y la licencia no puede exceder los siete días. Controlador abstracto
public abstract class AbstractHandler {
/**
* 下一个处理对象
*/
private AbstractHandler next;
/**
* 处理请假
*
* @param leaveDays 天数
* @return 处理结果
*/
public final String handleLeave(int leaveDays) {
if (this.getLeaveDays() >= leaveDays) {
return this.handle();
} else {
if (Objects.nonNull(next)) {
return next.handleLeave(leaveDays);
} else {
return "大老板都不能处理你的假期了~~";
}
}
}
/**
* 具体处理
*
* @return 处理结果
*/
protected abstract String handle();
/**
* 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了
*
* @return 请假天数
*/
protected abstract Integer getLeaveDays();
/**
* 设置下一个处理类
*
* @param next
*/
public void setNext(AbstractHandler next) {
this.next = next;
}
}
Manejador específico
// 项目经理处理
public class PMHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被项目经理处理了";
}
@Override
protected Integer getLeaveDays() {
return 1;
}
}
// 项目总监处理
public class PDHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被项目总监处理了";
}
@Override
protected Integer getLeaveDays() {
return 3;
}
}
// 大老板处理
public class BossHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被大老板处理了";
}
@Override
protected Integer getLeaveDays() {
return 7;
}
}
Cliente
@Test
public void test() {
PMHandler pmHandler = new PMHandler();
PDHandler pdHandler = new PDHandler();
BossHandler bossHandler = new BossHandler();
pmHandler.setNext(pdHandler);
pdHandler.setNext(bossHandler);
String leaveRes = pmHandler.handleLeave(1);
System.out.println(leaveRes);
String leaveRes1 = pmHandler.handleLeave(3);
System.out.println(leaveRes1);
String leaveRes2 = pmHandler.handleLeave(7);
System.out.println(leaveRes2);
String leaveRes3 = pmHandler.handleLeave(8);
System.out.println(leaveRes3);
}
Diagrama de clase
ventaja
- Reducir el acoplamiento. Desacopla el remitente y el receptor de la solicitud;
- Simplificado el objeto. Para que el objeto no necesite conocer la estructura de la cadena;
- Aumente la flexibilidad en la asignación de responsabilidades a los objetos. Al cambiar los miembros de la cadena o movilizar su orden, se permite agregar o eliminar responsabilidades dinámicamente;
- Es conveniente agregar nuevas clases de procesamiento de solicitudes.
Desventaja
- La solicitud no tiene un destinatario claro y no hay garantía de que será procesada. La solicitud no puede procesarse hasta el final de la cadena;
- Para una cadena de responsabilidad relativamente larga, el procesamiento de la solicitud puede involucrar múltiples objetos de procesamiento y el rendimiento del sistema se verá afectado en cierta medida.Además, no es conveniente depurar el código y puede causar llamadas circulares.
Escena aplicable
- Hay varios objetos que pueden manejar la misma solicitud, y qué objeto maneja la solicitud se determina automáticamente en tiempo de ejecución;
- Envíe una solicitud a uno de varios objetos sin especificar claramente el destinatario;
- Se puede designar dinámicamente un grupo de objetos para manejar solicitudes.
para resumir
Hay dos formas de uso del modelo de cadena de responsabilidad: el modelo de cadena pura de responsabilidad y el modelo de cadena impura de responsabilidad.
Si una clase es responsable de procesar la solicitud o patear la solicitud a la siguiente pelota, se llama modelo de cadena de responsabilidad pura; si una clase asume parte de la responsabilidad y también solicita patear la siguiente pelota, se llama impura. Modelo de cadena de responsabilidad. Es difícil encontrar ejemplos prácticos del modelo de cadena de responsabilidad pura, y los ejemplos que se ven comúnmente son la realización del modelo de cadena de responsabilidad impura.