El modelo de cadena de responsabilidad de patrones de diseño comunes

concepto

El patrón de cadena de responsabilidad (patrón de cadena de responsabilidad) trata cada nodo de la cadena como un objeto, cada nodo procesa diferentes solicitudes y mantiene internamente el siguiente objeto de nodo. Cuando se envía una solicitud desde el primer segmento de la cadena, se pasará a cada objeto de nodo por turno a lo largo de la ruta de la cadena hasta que un objeto maneje la solicitud. Este tipo de patrón de diseño es un patrón de comportamiento.
El modelo de cadena de responsabilidad incluye principalmente dos roles:

  • Manejador abstracto (Mango): Defina un método de procesamiento y mantenga una referencia al objeto Mango del siguiente nodo de procesamiento;
  • Mango de hormigón (ConcreteHandle): Procese la solicitud y reenvíela si no está interesado.

lograr

A continuación, tome la verificación de inicio de sesión como ejemplo

1. Crea un controlador abstracto

public abstract class Handle {
    
    
    protected Handle chain;

    public void next(Handle handle){
    
    
        this.chain=handle;
    }

    public abstract void doHandle(Member member);
}

2. Procesador específico

public class ValidateHadle extends Handle {
    
    
    @Override
    public void doHandle(Member member) {
    
    
        if("".equals(member.getName())||"".equals(member.getPwd())){
    
    
            System.out.println("用户名或密码为空");
            return;
        }
        System.out.println("用户名密码格式校验完毕");
        chain.doHandle(member);
    }
}
public class LoginHandle extends Handle {
    
    
    @Override
    public void doHandle(Member member) {
    
    
        System.out.println("登陆成功");
        chain.doHandle(member);
    }
}
public class AuthHandle extends Handle {
    
    
    @Override
    public void doHandle(Member member) {
    
    
        System.out.println("欢迎管理员!");
    }
}

3. Prueba

public class ChainTest {
    
    
    public static void main(String[] args) {
    
    
        Handle validateHandle=new ValidateHadle();
        Handle loginHandle=new LoginHandle();
        Handle authHandle=new AuthHandle();
        validateHandle.next(loginHandle);
        loginHandle.next(authHandle);
        validateHandle.doHandle(new Member("tom","123"));
    }
}

resultado de la operación:
Inserte la descripción de la imagen aquí

escenas que se utilizarán

  • Se procesa la misma solicitud para cada objeto, pero el procesamiento del objeto específico se determina dinámicamente en tiempo de ejecución
  • Envíe una solicitud a uno de varios objetos sin especificar claramente el destinatario
  • Puede especificar dinámicamente un grupo de objetos para procesar solicitudes

Aplicación en Spring Framework

En JDK, hay un filtro de clase muy común

public interface Filter {
    
    
    public void init(FilterConfig filterConfig) throws ServletException;
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
    public void destroy();

}

Esta interfaz de Filtro es muy simple, equivalente al rol abstracto de Manejar en la cadena de responsabilidad. Mirar de nuevodoFilterEl último parámetro en el método FilterChain class

public interface FilterChain {
    
    
    public void doFilter(ServletRequest request, ServletResponse response)
            throws IOException, ServletException;

}

Solo uno está definidodoFilterMétodo, ¿cómo se conectan para formar una cadena? Veamos la implementación de Spring de la clase MockFilterChain

public class MockFilterChain implements FilterChain {
    
    

	private ServletRequest request;

	private ServletResponse response;

	private final List<Filter> filters;

	private Iterator<Filter> iterator;
	public MockFilterChain() {
    
    
		this.filters = Collections.emptyList();
	}
	public MockFilterChain(Servlet servlet) {
    
    
		this.filters = initFilterList(servlet);
	}
	public MockFilterChain(Servlet servlet, Filter... filters) {
    
    
		Assert.notNull(filters, "filters cannot be null");
		Assert.noNullElements(filters, "filters cannot contain null values");
		this.filters = initFilterList(servlet, filters);
	}

	private static List<Filter> initFilterList(Servlet servlet, Filter... filters) {
    
    
		Filter[] allFilters = ObjectUtils.addObjectToArray(filters, new ServletFilterProxy(servlet));
		return Arrays.asList(allFilters);
	}
	public ServletRequest getRequest() {
    
    
		return this.request;
	}
	public ServletResponse getResponse() {
    
    
		return this.response;
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
    
    
		Assert.notNull(request, "Request must not be null");
		Assert.notNull(response, "Response must not be null");
		Assert.state(this.request == null, "This FilterChain has already been called!");

		if (this.iterator == null) {
    
    
			this.iterator = this.filters.iterator();
		}

		if (this.iterator.hasNext()) {
    
    
			Filter nextFilter = this.iterator.next();
			nextFilter.doFilter(request, response, this);
		}

		this.request = request;
		this.response = response;
	}
}

Pone todos los filtros de la cadena en la lista y luego llamadoFilterEl método es iterar la Lista, lo que significa que el Filtro en la Lista ejecutará el
diagrama de clases UML secuencialmente de la siguiente manera:
Inserte la descripción de la imagen aquí

para resumir

ventaja

  1. Desacoplar la solicitud del procesamiento
  2. Simplificado el objeto. Para que el objeto no necesite conocer la estructura de la cadena
  3. La estructura del enlace es flexible, puede agregar o eliminar responsabilidades dinámicamente cambiando la secuencia de la estructura del enlace
  4. Fácil ampliación de nuevas clases de procesamiento de solicitudes

Desventaja

  1. Si la cadena de responsabilidad es demasiado larga, el tiempo de procesamiento será demasiado largo, lo que afectará el rendimiento general.
  2. Si el objeto de nodo tiene referencias circulares, causará un bucle sin fin y hará que el sistema se bloquee

Supongo que te gusta

Origin blog.csdn.net/xzw12138/article/details/106711267
Recomendado
Clasificación