Patrones de diseño_Patrones de comportamiento - "Cadena de patrones de responsabilidad"

Patrones de diseño_Patrones de comportamiento - "Cadena de patrones de responsabilidad"

Las notas están organizadas a partir de la explicación detallada de los patrones de diseño de Java por programadores de caballos oscuros, 23 patrones de diseño de Java (diagrama + análisis de código fuente del marco + combate real)

descripción general

En la vida real, a menudo se dan estos casos: varios objetos pueden procesar una solicitud, pero las condiciones de procesamiento o los permisos de cada objeto son diferentes. Por ejemplo, si un empleado de la empresa solicita una licencia, los líderes que pueden aprobar la licencia son el jefe de departamento, el subgerente general, el gerente general, etc., pero la cantidad de días que cada líder puede aprobar es diferente. los líderes firmen de acuerdo a la cantidad de días que quieren pedir licencia, es decir, los empleados deben recordar información como el nombre, teléfono y dirección de cada líder, lo que aumenta la dificultad. Hay muchos otros ejemplos como este, como buscar el reembolso de los viajes de negocios de los líderes y el juego de "tocar el tambor y pasar flores" en la vida diaria.

definición

  • El modo de cadena de responsabilidad, también conocido como modo de cadena de responsabilidad, para evitar acoplar al remitente de la solicitud con múltiples procesadores de solicitudes, todos los procesadores de solicitudes se conectan en una cadena al recordar la referencia del siguiente objeto a través del objeto anterior; cuando ocurre una solicitud , la solicitud se puede pasar a lo largo de esta cadena hasta que un objeto la maneje.

imagen-20230109124843959

estructura

El Patrón de Cadena de Responsabilidad incluye principalmente los siguientes roles:

  • Rol de controlador abstracto (Handler): define una interfaz para procesar solicitudes, incluidos métodos de procesamiento abstracto y una conexión posterior (una referencia al siguiente objeto).
  • Rol de controlador concreto (Concrete Handler): implementa el método de procesamiento del controlador abstracto, juzga si la solicitud se puede procesar, si puede manejar la solicitud, procesarla, de lo contrario, transferir la solicitud a su sucesor.
  • Rol de clase de cliente (Cliente): cree una cadena de procesamiento y envíe una solicitud al objeto de procesador específico en la cabeza de la cadena. No le importan los detalles de procesamiento y el proceso de entrega de la solicitud.

Realización de casos

Ahora es necesario desarrollar un sistema de control de procesos de licencia. La licencia de menos de 1 día solo necesita la aprobación del líder del equipo; la licencia de 1 a 3 días requiere la aprobación del gerente del departamento; la licencia de 3 a 7 días requiere la aprobación del gerente general.

El diagrama de clases es el siguiente:

el código se muestra a continuación:

  • solicitud escrita de licencia

    public class LeaveRequest {
          
          
        
        private String name; // 姓名
        private int num; // 请假天数
        private String content; // 请假内容
    
        public LeaveRequest(String name, int num, String content) {
          
          
            this.name = name;
            this.num = num;
            this.content = content;
        }
    
        public String getName() {
          
          
            return name;
        }
    
        public int getNum() {
          
          
            return num;
        }
    
        public String getContent() {
          
          
            return content;
        }
    }
    
  • rol de controlador abstracto

    public abstract class Handler {
          
          
        
        protected final static int NUM_ONE = 1;
        protected final static int NUM_THREE = 3;
        protected final static int NUM_SEVEN = 7;
    
        // 该领导处理的请假天数区间
        private int numStart;
        private int numEnd;
    
        // 领导上面还有领导(后继连接,下一个对象的引用)
        private Handler nextHandler;
    
        // 设置请假天数范围 上不封顶
        public Handler(int numStart) {
          
          
            this.numStart = numStart;
        }
    
        // 设置请假天数范围
        public Handler(int numStart, int numEnd) {
          
          
            this.numStart = numStart;
            this.numEnd = numEnd;
        }
    
        // 设置上级领导
        public void setNextHandler(Handler nextHandler){
          
          
            this.nextHandler = nextHandler;
        }
    
        // 提交请假条
        public final void submit(LeaveRequest leave){
          
          
            if (0 == this.numStart) {
          
          
                return;
            }
    
            // 如果请假天数达到该领导者的处理要求
            if (leave.getNum() >= this.numStart) {
          
          
                this.handleLeave(leave);
    
                // 如果还有上级 并且请假天数超过了当前领导的处理范围
                if (this.nextHandler != null && leave.getNum() > numEnd) {
          
          
                    this.nextHandler.submit(leave); // 继续往上提交 责任链模式
                } else {
          
          
                    System.out.println("流程结束");
                }
            }
        }
    
        // 各级领导处理请假条方法
        protected abstract void handleLeave(LeaveRequest leave);
    }
    
  • Papel del procesador de hormigón

    // 具体处理者-小组长
    public class GroupLeader extends Handler {
          
          
        public GroupLeader() {
          
          
            // 小组长处理1天以下的请假
            super(0, Handler.NUM_ONE);
        }
    
        @Override
        protected void handleLeave(LeaveRequest leave) {
          
          
            System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
            System.out.println("小组长审批:同意。");
        }
    }
    
    // 具体处理者-部门经理
    public class Manager extends Handler {
          
          
        public Manager() {
          
          
            // 部门经理处理1-3天的请假
            super(Handler.NUM_ONE, Handler.NUM_THREE);
        }
    
        @Override
        protected void handleLeave(LeaveRequest leave) {
          
          
            System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
            System.out.println("部门经理审批:同意。");
        }
    }
    
    // 具体处理者-总经理
    public class GeneralManager extends Handler {
          
          
        public GeneralManager() {
          
          
            // 部门经理处理3-7天的请假
            super(Handler.NUM_THREE, Handler.NUM_SEVEN);
        }
    
        @Override
        protected void handleLeave(LeaveRequest leave) {
          
          
            System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
            System.out.println("总经理审批:同意。");
        }
    }
    
  • clase de prueba

    public class Client {
          
          
        public static void main(String[] args) {
          
          
            // 请假条来一张
            LeaveRequest leave = new LeaveRequest("张三", 5, "身体不适");
    
            // 各位领导
            GroupLeader groupLeader = new GroupLeader();
            Manager manager = new Manager();
            GeneralManager generalManager = new GeneralManager();
    
            groupLeader.setNextHandler(manager); // 小组长的领导是部门经理
            manager.setNextHandler(generalManager); // 部门经理的领导是总经理
            // 此时责任链已经设置成功了
            // 之所以在这里设置上级领导,是因为可以根据实际需求来更改设置,如果实战中上级领导人都是固定的,则可以移到领导实现类中。
    
            // 提交申请
            groupLeader.submit(leave);
        }
    }
    

    producción

    张三请假5天,身体不适。
    小组长审批:同意
    张三请假5天,身体不适。
    部门经理审批:同意
    张三请假5天,身体不适。
    总经理审批:同意
    流程结束!
    

Ventajas y desventajas

ventaja

  • Acoplamiento reducido entre objetos
    • Este patrón reduce el acoplamiento entre el emisor y el receptor de la solicitud.
  • Escalabilidad mejorada del sistema
    • Se pueden agregar nuevas clases de procesamiento de solicitudes según sea necesario para cumplir con el principio de apertura y cierre.
  • Mayor flexibilidad en la asignación de responsabilidades a los objetos
    • Cuando cambia el flujo de trabajo, puede cambiar dinámicamente los miembros de la cadena o modificar su orden, y también puede agregar o eliminar responsabilidades dinámicamente.
  • Chain of Responsibility simplifica la conexión entre objetos
    • Un objeto solo necesita mantener una referencia que apunte a su sucesor, y no necesita mantener referencias a todos los demás controladores, lo que evita el uso de numerosas declaraciones if o if···else.
  • responsabilidad compartida
    • Cada clase solo necesita manejar el trabajo que debe manejar y pasar los no manejados al siguiente objeto para completar, aclarar el alcance de la responsabilidad de cada clase y cumplir con el principio de responsabilidad única de la clase.

defecto

  • No hay garantía de que todas las solicitudes sean procesadas. Dado que una solicitud no tiene un destinatario claro, no hay garantía de que se procesará, y la solicitud puede pasar por toda la cadena sin ser procesada.
  • En comparación con una larga cadena de responsabilidad, el procesamiento de la solicitud puede involucrar múltiples objetos de procesamiento y el rendimiento del sistema se verá afectado hasta cierto punto.
  • La racionalidad del establecimiento de la cadena de responsabilidad depende de la garantía del cliente, lo que aumenta la complejidad del cliente y puede causar errores en el sistema debido a configuraciones incorrectas de la cadena de responsabilidad, como llamadas circulares.

Análisis de código fuente-JavaWeb

En el desarrollo de aplicaciones JavaWeb, FilterChain es una aplicación típica del patrón de cadena de responsabilidad (filtro). El siguiente es el análisis de implementación de simulación de Filter:

  • Simular solicitud web Solicitud y respuesta web Respuesta

    public interface Request {
          
          
     
    }
    
    public interface Response {
          
          
     
    }
    
  • Filtro web analógico Filtro

    public interface Filter {
          
          
    	public void doFilter(Request req, Response res, FilterChain c);
    }
    
  • Simular la implementación de filtros de hormigón

    public class FirstFilter implements Filter {
          
          
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
          
          
    
            System.out.println("过滤器1 前置处理");
    
            // 先执行所有request再倒序执行所有response
            chain.doFilter(request, response);
    
            System.out.println("过滤器1 后置处理");
        }
    }
    
    public class SecondFilter implements Filter {
          
          
        @Override
        public void doFilter(Request request, Response response, FilterChain chain) {
          
          
    
            System.out.println("过滤器2 前置处理");
    
            // 先执行所有request再倒序执行所有response
            chain.doFilter(request, response);
    
            System.out.println("过滤器2 后置处理");
        }
    }
    
  • Simular la implementación de la cadena de filtros FilterChain

    public class FilterChain {
          
          
    
        private List<Filter> filters = new ArrayList<Filter>();
    
        private int index = 0;
    
        // 创建过滤器链对象 -> 链式调用
        public FilterChain addFilter(Filter filter) {
          
          
            this.filters.add(filter);
            return this;
        }
    
        public void doFilter(Request request, Response response) {
          
          
            if (index == filters.size()) {
          
          
                return;
            }
            Filter filter = filters.get(index);
            index++;
            filter.doFilter(request, response, this);
        }
    }
    
  • clase de prueba

    public class Client {
          
          
        public static void main(String[] args) {
          
          
            Request  req = null;
            Response res = null;
    
            FilterChain filterChain = new FilterChain();
            filterChain.addFilter(new FirstFilter()).addFilter(new SecondFilter());
            filterChain.doFilter(req, res);
        }
    }
    

    producción

    过滤器1 前置处理
    过滤器2 前置处理
    过滤器2 后置处理
    过滤器1 后置处理
    

Supongo que te gusta

Origin blog.csdn.net/weixin_53407527/article/details/128628042
Recomendado
Clasificación