责任链模式
每个类都有是否可以处理它的任务方法,如果不能就将任务转到下一个类,以此类推所有的类组成一个链。(官方一点的话:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。)
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
优点:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点:
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。
使用场景:
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
应用的例子:
我们有一个字符串 String msg = ":):,<script>,敏感,被就业,网络授课";
我们希望应用以下三个规则对字符串进行过滤和谐处理:
1.将字符串中出现的"<>“符号替换成”[]"
2.处理字符串中的敏感信息,将 “被就业” 和谐 “成就业”
3.将字符串中出现的 ":):"
转换成 "^V^"
;
请求类:
/**
* 封装请求的类Request
*/
public class Request {
String requestStr;
public String getRequestStr() {
return requestStr;
}
public void setRequestStr(String requestStr) {
this.requestStr = requestStr;
}
}
响应类:
/**
* 封装响应信息的类Response
*/
public class Response {
String responseStr;
public String getResponseStr() {
return responseStr;
}
public void setResponseStr(String responseStr) {
this.responseStr = responseStr;
}
}
任务处理方法:
/**
* 定义接口Filter,具体的过滤规则需要实现这个接口,最后一个参数添加的意义是我们在Main函数中:
* fc.doFilter(request, response,fc);执行这一步的时候可以按照规则链条一次使用三个过滤规则对字符串进行处理
*/
public interface MyFilter {
void doFilter(Request request, Response response, MyFilterChain filterChain);
}
任务处理方法实现类(责任类):
public class SensitiveFilter implements MyFilter {
@Override
public void doFilter(Request request, Response response, MyFilterChain filterChain) {
System.out.println(Thread.currentThread().getId()+" 1");
request.requestStr = request.requestStr.replace("被就业", "就业").replace("敏感", "") + "------来自SensitiveFilter";
response.responseStr += "------sensitiveFilter()";
filterChain.doFilter(request, response, filterChain);
}
}
public class FaceFilter implements MyFilter {
@Override
public void doFilter(Request request, Response response, MyFilterChain filterChain) {
System.out.println(Thread.currentThread().getId()+" 1");
request.requestStr = request.requestStr.replace(":):", "^V^") + "----FaceFilter()";
response.responseStr += "---FaceFilter()";
filterChain.doFilter(request, response, filterChain);
}
}
public class HTMLFilter implements MyFilter {
@Override
public void doFilter(Request request, Response response, MyFilterChain filterChain) {
System.out.println(Thread.currentThread().getId()+" 1");
request.requestStr = request.requestStr.replace('<','[').replace('>','}') + "------来自HTMLFilter";
response.responseStr += "----HTMLFilter()";
filterChain.doFilter(request,response,filterChain);
}
}
定义责任链MyFilterChain:
public class MyFilterChain {
//用List集合来存储过滤规则(按照添加顺序存放所有责任类)
List<MyFilter> filters = new ArrayList<MyFilter>();
//用于标记规则的引用顺序
int index = 0;
//往规则链条中添加规则
public MyFilterChain addFilter(MyFilter filter) {
filters.add(filter);
//代码的设计技巧:Chain链添加过滤规则结束后返回添加后的Chain,方便我们下面doFilter函数的操作
return this;
}
public void doFilter(Request request, Response response, MyFilterChain filterChain) {
//index初始化为0,filters.size()为3,不会执行return操作
if(index == filters.size()) {
return;
}
//每执行一个责任类,index就自增
MyFilter f = filters.get(index);
index ++;
//根据索引值获取对应的规律规则对字符串进行处理
f.doFilter(request, response, filterChain);
}
}
public static void main(String[] args) {
String requestStr = ":):,<script>,敏感,被就业,网络授课";
Request request = new Request();
request.setRequestStr(requestStr);
Response response = new Response();
response.setResponseStr("response:");
//new出责任链
MyFilterChain chain = new MyFilterChain();
//new出责任类
HTMLFilter htmlFilter = new HTMLFilter();
FaceFilter faceFilter = new FaceFilter();
SensitiveFilter sensitiveFilter = new SensitiveFilter();
//将责任类存到责任链的集合中
chain.addFilter(htmlFilter);
chain.addFilter(faceFilter);
chain.addFilter(sensitiveFilter);
//执行这个责任链上的所有责任类
chain.doFilter(request, response, chain);
System.out.println(request.getRequestStr());
System.out.println(response.getResponseStr());
}
结果:
借鉴于:
https://www.cnblogs.com/happyflyingpig/p/7731980.html