浅谈设计模式之责任链模式
责任链模式主要是解决请求端和多个接收端之间的耦合,比如原来一个请求进来需要多个接受者进行处理,如果把这些接收者串在一起形成一个链条,然后统一交给一个中间人去管理,这样就达到请求者和接受者直接的耦合。下面我们通过servlet中经典的过滤器例子来解释责任链模式。
模拟servlet中的filter
需求: 模拟http请求到具体的controller之前,进行请求过滤,通过过滤器进行对请求进行加工或者判断。我们这边模拟两个过滤器,一个是Url过滤器,一个jwt过滤器;
- Url过滤器:只有url为特定url的才能通过
- jwt过滤器:只有特定的用户才能通过
类图:
代码实现
模拟的请求类:
/**
* 请求类
*/
public class Request {
public String url;
public String username;
public Request(String url, String username) {
this.url = url;
this.username = username;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
过滤器责任链类:
/**
* 过滤器责任链
*/
public interface FilterChain {
/**
* 过滤
* @param req
*/
void doFilter(Request req);
}
import java.util.List;
/**
* 自定义责任链类
*/
public class MyFilterChain implements FilterChain {
private List<Filter> filters;
private int index = 0;
public MyFilterChain(List<Filter> filters) {
this.filters = filters;
}
@Override
public void doFilter(Request req) {
if (filters == null || this.filters.size() == this.index) {
System.out.println("完成过滤");
} else {
this.filters.get(this.index++).doFilter(req, this);
}
}
}
过滤器类:
public interface Filter {
/**
* 过滤器过滤方法
*
* @param req
* @param chain
*/
void doFilter(Request req, FilterChain chain);
}
public class JwtFilter implements Filter {
@Override
public void doFilter(Request req, FilterChain chain) {
String username = req.getUsername();
if ("test".equals(username)) {
System.out.println("jwt过滤器通过");
chain.doFilter(req);
} else {
System.out.println("用户名不合法");
}
}
}
public class UrlFilter implements Filter {
@Override
public void doFilter(Request req, FilterChain chain) {
String url = req.getUrl();
//假设url只有等于test才能访问,其他的输出不能访问即可
if ("test".equals(url)) {
System.out.println("url过滤器通过");
chain.doFilter(req);
} else {
System.out.println("url错误");
}
}
}
客户端测试类:
public class Client {
public static void main(String[] args) {
Request request = new Request("test", "test");
List<Filter> filters = new ArrayList<>();
filters.add(new UrlFilter());
filters.add(new JwtFilter());
FilterChain filterChain = new MyFilterChain(filters);
filterChain.doFilter(request);
}
}
我们来看下运行结果:
url过滤器通过
jwt过滤器通过
完成过滤
如果改变request对象的值Request request = new Request("test", "zhangsan");
我们再来看看运行结果:
url过滤器通过
用户名不合法
从以上结果我们可以看出我们已经可以根据请求参数完成不同的过滤效果
总结
责任链模式可以让我们将原来一系列可能繁琐的操作串到一个链条上,从而达到请求与处理解耦,又易于后续扩展,比如后续有新的过滤规则只要新增一个过滤器将过滤器加到链条当中就可以完成过滤效果。好了,责任链模式就分享到这,欢迎拍砖。