设计模式-行为型模式-装饰者模式 Chain Of Redponsibility
1.简介
计算机软件是用来处理信息的,有多种维度或者方向去处理信息; 我们设计编程中的对象时,应该赋予一个类单一的职责;这样可以类更加扩展和维护;
基于这个场景,我们设计一系列的处理信息的类按照不同规则去处理类,而不是把所有的规则添加到一个类里面来,这样使得规则更容易扩展和维护;
这些类被称之为处理器,处理器处理请求,处理后给下一个处理,以此类推到最后一个;
如下图所示
2.角色
角色
- Client:客户端,会实例化一个处理器链对象,调用 handleRequest(request) 方法
- Handler:处理器抽象类,接口类
- ConcreteHandler:实现Handler 的handleRequest 方法,需要检测自身是否可以处理请求,和传递给下一个处理器的能力 ;
3.场景
java 的 Servlet 标准中的Filter 和FilterChain,用来处理和过滤请求
看看 Servlet 里面的约定 和
package javax.servlet;
//过滤器(处理器)
public interface Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
}
//过滤器链(处理器链)
public interface FilterChain {
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException;
}
Tomcat 里面的部分 Filter实现 和调用
public abstract class FilterBase implements Filter
// HttpHeader 安全过滤器 过滤器的实现有很多
public class HttpHeaderSecurityFilter extends FilterBase {
.....
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
.....
}
//过滤器链(处理器链) 的实现 就一个
public final class ApplicationFilterChain implements FilterChain {
/**
* The int which is used to maintain the current position
* in the filter chain. 维护当前位置
*/
private int pos = 0;
@Override
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
.....
filter.doFilter(request, response, this);
......
}
看完了 Tomcat 的实现 自己来实现一把!!
先定义几个接口
interface Filter {
//Boolean 用来控制对出
Boolean doFilter(Request request, Response response, FilterChain chain);
}
class Request {
public Request(String msg) {
Msg = msg;
}
private String Msg;
public String getMsg() {
return Msg;
}
public void setMsg(String msg) {
Msg = msg;
}
}
class Response {
private String Msg;
public String getMsg() {
return Msg;
}
public void setMsg(String msg) {
Msg = msg;
}
}
两个处理器的实现
class sensitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
String msg = response.getMsg() == null ? request.getMsg() : response.getMsg();
String replace = msg.replace("福报", "财富");
System.out.println("before 敏感词 Filter");
chain.doFilter(request, response);
System.out.println("after 敏感词 Filter");
response.setMsg(replace);
}
}
class cssFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
String msg = response.getMsg() == null ? request.getMsg() : response.getMsg();
String replace = msg.replace("<", "[").replace(">", "]");
System.out.println("before css Filter");
chain.doFilter(request, response);
System.out.println("after css Filter");
response.setMsg(replace);
}
}
处理器链的实现
class FilterChain {
List<Filter> filters = new ArrayList<>();
int index = 0;
public FilterChain addFilter(Filter filter) {
filters.add(filter);
return this;
}
public void doFilter(Request request, Response response) {
if (index == filters.size()) {
// 最后一个
return;
}
// 获取当前的
Filter f = filters.get(index);
index++;
f.doFilter(request, response, this);
}
}
测试方法
public static void main(String[] args) {
Request request = new Request("老板说,你们程序员应该996 ,这样才能获取福报 <script>, 代码上问题可以上百度搜索, 不要在公开场合放屁");
FilterChain filterChain = new FilterChain().addFilter(new sensitiveFilter()).addFilter(new cssFilter());
Response response = new Response();
filterChain.doFilter(request, response);
System.out.println(response.getMsg());
}
效果是
before 敏感词 Filter
before css Filter
after css Filter
after 敏感词 Filter
到此 完成 ,,拙劣的模范;