Chain of Responsibility概述
玩具代码案例-一个简单的链式调用
链式处理器接口
IChainHandler
package online.javabook.gof.behavioral.patterns1.chain;
public abstract class IChainHandler {
private IChainHandler next;
public void setNext(IChainHandler next) {
this.next = next;
}
public abstract void handle(String request);
public void nextHandler(String request) {
if(next != null) {
next.handle(request);
}
}
}
链式处理器实现
ChainHandler1
package online.javabook.gof.behavioral.patterns1.chain;
public class ChainHandler1 extends IChainHandler {
@Override
public void handle(String request) {
System.out.println(this.getClass().getSimpleName() + ": handler " + request);
nextHandler(request);
}
}
ChainHandler2
package online.javabook.gof.behavioral.patterns1.chain;
public class ChainHandler2 extends IChainHandler {
@Override
public void handle(String request) {
System.out.println(this.getClass().getSimpleName() + ": handler " + request);
nextHandler(request);
}
}
ChainHandler3
package online.javabook.gof.behavioral.patterns1.chain;
public class ChainHandler3 extends IChainHandler {
@Override
public void handle(String request) {
System.out.println(this.getClass().getSimpleName() + ": handler " + request);
nextHandler(request);
}
}
链式处理器调用
Main
package online.javabook.gof.behavioral.patterns1.chain.app;
import online.javabook.gof.behavioral.patterns1.chain.ChainHandler1;
import online.javabook.gof.behavioral.patterns1.chain.ChainHandler2;
import online.javabook.gof.behavioral.patterns1.chain.ChainHandler3;
import online.javabook.gof.behavioral.patterns1.chain.IChainHandler;
public class Main {
public static void main(String[] args) {
IChainHandler chainHandler1 = new ChainHandler1();
IChainHandler chainHandler2 = new ChainHandler2();
IChainHandler chainHandler3 = new ChainHandler3();
chainHandler1.setNext(chainHandler2);
chainHandler2.setNext(chainHandler3);
chainHandler1.handle("request");
}
}
Console
ChainHandler1: handler request
ChainHandler2: handler request
ChainHandler3: handler request
现实世界中的过滤器模式
Java Web程序员在现实世界中接触的第一个过滤器模式的设计应该就是 javax.sevlets下的Filter和FilterChain。
Filter
package javax.servlet;
import java.io.IOException;
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
default void destroy() {
}
}
package javax.servlet.http;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.GenericFilter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public abstract class HttpFilter extends GenericFilter {
public HttpFilter() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {
this.doFilter((HttpServletRequest)req, (HttpServletResponse)res, chain);
} else {
throw new ServletException("non-HTTP request or response");
}
}
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, res);
}
}
FilterChain
package javax.servlet;
import java.io.IOException;
public interface FilterChain {
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
package org.springframework.mock.web;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
public class MockFilterChain implements FilterChain {
@Nullable
private ServletRequest request;
@Nullable
private ServletResponse response;
private final List<Filter> filters;
@Nullable
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 = (Filter[])ObjectUtils.addObjectToArray(filters, new MockFilterChain.ServletFilterProxy(servlet));
return Arrays.asList(allFilters);
}
@Nullable
public ServletRequest getRequest() {
return this.request;
}
@Nullable
public ServletResponse getResponse() {
return this.response;
}
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 = (Filter)this.iterator.next();
nextFilter.doFilter(request, response, this);
}
this.request = request;
this.response = response;
}
public void reset() {
this.request = null;
this.response = null;
this.iterator = null;
}
private static final class ServletFilterProxy implements Filter {
private final Servlet delegateServlet;
private ServletFilterProxy(Servlet servlet) {
Assert.notNull(servlet, "servlet cannot be null");
this.delegateServlet = servlet;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
this.delegateServlet.service(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public String toString() {
return this.delegateServlet.toString();
}
}
}