责任链模式:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
一、设计模式类图
二、开发中的应用(废话不多说,直接上代码)
package com.hongyan.res;
import java.util.ArrayList;
import java.util.List;
/**
* 责任链模式简单示例
*
* @author hy
* @date 2022/01/25
*/
public class Respon {
public static void main(String[] args) {
Msg m = new Msg();
m.setMessage("大家好:),欢迎大家访问 hongyanketang ,虎年大吉, <tr>");
// 过滤链条1
FilterChain fc = new FilterChain();
fc.add(new HTMLFilter()).add(new SensitiveFilter());
// 过滤链条2
FilterChain fc2 = new FilterChain();
fc2.add(new FaceFilter()).add(new URLFilter());
fc.add(fc2);
fc.doFilter(m);
System.out.println(m);
// Msg{message='大家好:),欢迎大家访问 hongyanketang ,虎年大吉, [tr]'}
}
}
class Msg {
String username;
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "Msg{" +
"message='" + message + '\'' +
'}';
}
}
interface Filter { boolean doFilter(Msg m);}
class HTMLFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMessage();
r = r.replaceAll("<", "[").replaceAll(">", "]");
m.setMessage(r);
return true;
}
}
class SensitiveFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMessage();
r = m.getMessage().replaceAll("996", "955");
m.setMessage(r);
return false;
}
}
class FaceFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMessage();
r = m.getMessage().replaceAll(":\\)", "^V^");
m.setMessage(r);
return true;
}
}
class URLFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMessage();
r = m.getMessage().replaceAll("hongyanketang.com", "http://www.hongyanketang.com");
m.setMessage(r);
return true;
}
}
class FilterChain implements Filter{
private final List<Filter> filters = new ArrayList<>();
public FilterChain add(Filter filter) {
this.filters.add(filter);
return this;
}
public boolean doFilter(Msg m) {
for(Filter f : filters) {
if(!f.doFilter(m)) return false;
}
return true;
}
}
三、框架中的 WebFilterChain 过滤器链应用(有点难度),有兴趣可以翻翻源码。
以下是一个类似的实例,实现的效果如图
package com.hongyan.servlet;
import java.util.ArrayList;
import java.util.List;
/**
* 有顺序的责任链
*
* @author hy
* @date 2022/01/25
*/
public class Test {
public static void main(String[] args) {
Request request = new Request();
request.str = "新年快乐<html>,欢迎访问 hongyanketang.com </html> ";
Response response = new Response();
response.str = "response";
FilterChain chain = new FilterChain();
chain.add(new HTMLFilter()).add(new SensitiveFilter());
chain.doFilter(request, response);
System.out.println(request.str);
System.out.println(response.str);
// 从结果可以发现,request 和 response 都是有序执行
// 新年快乐[html],欢迎访问 hongyanketang.com [/html] HTMLFilter() SensitiveFilter()
// response--SensitiveFilter()--HTMLFilter()
}
}
interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
class HTMLFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.str = request.str.replaceAll("<", "[").replaceAll(">", "]") + "HTMLFilter()";
chain.doFilter(request, response);
response.str += "--HTMLFilter()";
}
}
class Request {
String str;
}
class Response {
String str;
}
class SensitiveFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
request.str = request.str.replaceAll("996", "955") + " SensitiveFilter()";
chain.doFilter(request, response);
response.str += "--SensitiveFilter()";
}
}
class FilterChain {
List<Filter> filters = new ArrayList<>();
int index = 0;
public FilterChain add(Filter f) {
filters.add(f);
return this;
}
/**
* 递归遍历,从而使每个请求先处理 request,然后再处理 response
*
* @param request
* @param response
*/
public void doFilter(Request request, Response response) {
if(index == filters.size()) return;
Filter f = filters.get(index);
index ++;
f.doFilter(request, response, this);
}
}
总结:这个模式有点难度,细细琢磨你会发现其中的奥秘。