责任链模式- 2020-12-01 23:05- 设计模式: 责任链模式,设计模式
概念
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
模拟ServeltFitler实现责任链
模拟请求对象 ServletRequest
/**
* 模拟请求对象 ServletRequest
*
* @author Bai
* @date 2020/12/1 21:34
*/
@Data
public class Request {
/**
* 请求消息
*/
private String msg;
/**
* 上下文
*/
private String text;
}
模拟响应对象ServletResponse
/**
* 响应
*
* @author Bai
* @date 2020/12/1 21:34
*/
@Data
public class Response {
/**
* 响应消息
*/
private String msg;
/**
* 上下文
*/
private String text;
}
模拟Filter对象:javax.servlet.Filter
/** 请求过滤器
* @author Bai
* @date 2020/12/1 21:33
*/
public interface Filter {
/**
* @param request 请求
* @param response 响应
* @param filterChain 责任链
* @return
*/
boolean doFilter(Request request, Response response, FilterChain filterChain);
}
自定义Filter
/**
* 替换指定文本
*
* @author Bai
* @date 2020/12/1 21:44
*/
public class TextFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
request.setText(request.getText() + "TextFilter() ");
//请求主要逻辑处理
request.setMsg(request.getMsg().replace("加班", "休息"));
request.setMsg(request.getMsg().replace("破解", "使用"));
//调用下一个节点
filterChain.doFilter(request, response, filterChain);
//处理响应
response.setText(response.getText() + "TextFilter() ");
return true;
}
}
/**
* 非法字符替换
*
* @author Bai
* @date 2020/12/1 21:53
*/
public class IllegalSymbolFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
request.setText(request.getText() + "IllegalSymbolFilter() ");
//请求主要逻辑处理
request.setMsg(request.getMsg().replace("<", "{"));
request.setMsg(request.getMsg().replace(">", "}"));
//调用下一个节点
filterChain.doFilter(request, response, filterChain);
//处理响应
response.setText(response.getText() + "IllegalSymbolFilter() ");
return true;
}
}
模拟责任链 javax.servlet.FilterConfig
/**
* 责任链
* 实现 Filter 意味着本身也可以作为责任链中的一个节点 加入另外一个责任链
*
* @author Bai
* @date 2020/12/1 21:36
*/
public class FilterChain implements Filter {
/**
* 集合下标,每执行一次节点+1
*/
private int index = 0;
/**
* 存放每个节点的 filter
*/
private List<Filter> FILTER_LIST = new ArrayList<>();
/**
* 向集合中添加节点
*
* @param filter
* @return 可以使用连式编程
*/
public FilterChain add(Filter filter) {
FILTER_LIST.add(filter);
return this;
}
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
//执行到最后一个节点后 不再执行
if (index >= FILTER_LIST.size()) {
return false;
}
//每次只执行指定的节点
Filter filter = FILTER_LIST.get(index++);
//每执行一个节点+1
return filter.doFilter(request, response, filterChain);
}
}
模拟一次请求
@Test
public void dome() {
//模拟一次请求
Request request = new Request();
request.setMsg("<javaScript>hello,我是黑客,我在加班,破解你们的系统");
request.setText("start -> ");
//响应
Response response = new Response();
response.setMsg("end -> ");
//生成责任链
FilterChain chain = new FilterChain();
//添加节点
chain.add(new TextFilter());
chain.add(new IllegalSymbolFilter());
chain.doFilter(request, response, chain);
System.out.println(request.getMsg());
System.out.println(request.getText());
System.out.println(response.getText());
}
{javaScript}hello,我是黑客,我在休息,使用你们的系统
start -> TextFilter() IllegalSymbolFilter()
nullIllegalSymbolFilter() TextFilter()
将责任链作为节点
/**
* 责任链做为另外一个责任链的节点
*/
@Test
public void dome2() {
//模拟一次请求
Request request = new Request();
request.setMsg("<javaScript>hello,我是黑客,我在加班,破解你们的系统");
request.setText("start -> ");
//响应
Response response = new Response();
response.setMsg("end -> ");
//生成责任链
FilterChain chain = new FilterChain();
chain.add(new TextFilter());
FilterChain chain2 = new FilterChain();
//将责任链作为另外一个链路的节点
chain2.add(new IllegalSymbolFilter());
chain.add(chain2);
chain.doFilter(request, response, chain);
System.out.println(request.getMsg());
System.out.println(request.getText());
System.out.println(response.getText());
}
**