标签:ring patch actor proc strong test factor cep rgs
责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。
这种模式给予请求的类型,对请求的发送者和接收者进行解耦。属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
先来看一段代码
public void test(int i, Request request){
if(i==1){
Handler1.response(request);
}else if(i == 2){
Handler2.response(request);
}else if(i == 3){
Handler3.response(request);
}else if(i == 4){
Handler4.response(request);
}else{
Handler5.response(request);
}
}
代码的业务逻辑是这样的,方法有两个参数:整数 i 和一个请求 request,根据 i 的值来决定由谁来处理 request,如果 i1,由 Handler1来处理,如果 i2,由 Handler2 来处理,以此类推。在编程中,这种处理业务的方法非常常见,所有处理请求的类由if…else…条件判断语句连成一条责任链来对请求进行处理,相信大家都经常用到。这种方法的优点是非常直观,简单明了,并且比较容易维护,但是这种方法也存在着几个比较令人头疼的问题:
既然缺点我们已经清楚了,就要想办法来解决。这个场景的业务逻辑很简单:如果满足条件1,则由 Handler1 来处理,不满足则向下传递;如果满足条件2,则由 Handler2 来处理,不满足则继续向下传递,以此类推,直到条件结束。其实改进的方法也很简单,就是把判定条件的部分放到处理类中,这就是责任连模式的原理。
责任链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
public abstract class Handler {
private Handler nextHandler;
private int level;
public Handler(int level) {
this.level = level;
}
public void setNextHandler(Handler handler){
this.nextHandler = handler;
}
public final void handlerRequest(Request request){
if(level == request.getLevel()){
this.response(request);
}else{
if (this.nextHandler != null){
this.nextHandler.handlerRequest(request);
}else{
System.out.println("===已经没有处理器了===");
}
}
}
// 抽象方法,子类实现
public abstract void response(Request request);
}
class Request {
int level = 0;
public Request(int level){
this.level = level;
}
public int getLevel() {
return level;
}
}
public class ConcreteHandler1 extends Handler {
public ConcreteHandler1(int level) {
super(level);
}
@Override
public void response(Request request) {
System.out.println("请求由处理器1进行处理");
}
}
public class ConcreteHandler2 extends Handler {
//...
}
public class ConcreteHandler2 extends Handler {
//...
}
public class Client {
public static void main(String[] args) {
ConcreteHandler1 handler1 = new ConcreteHandler1(1);
ConcreteHandler2 handler2 = new ConcreteHandler2(2);
ConcreteHandler3 handler3 = new ConcreteHandler3(3);
//处理者构成一个环形
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
handler1.handlerRequest(new Request(1));
}
}
当你想要让一个以上的对象有机会能够处理某个请求的时候,就是用责任链模式。
通过责任链模式,你可以为某个请求创建一个对象链。每个对象依序检查此请求,并对其进行处理,或者将它传给链中的下一个对象。
比如
JAVA 中的异常处理机制、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,JSP、Servlet 的 Filter 均是责任链的典型应用。
public final class ApplicationFilterChain implements FilterChain {
private static final ThreadLocal<ServletRequest> lastServicedRequest;
private static final ThreadLocal<ServletResponse> lastServicedResponse;
public static final int INCREMENT = 10;
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0; //下一个要执行的filter的位置
private int n = 0; //filter个数
private Servlet servlet = null;
public ApplicationFilterChain() {
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (Globals.IS_SECURITY_ENABLED) {
final ServletRequest req = request;
final ServletResponse res = response;
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
public Void run() throws ServletException, IOException {
ApplicationFilterChain.this.internalDoFilter(req, res);
return null;
}
});
} catch (PrivilegedActionException var7) {
Exception e = var7.getException();
if (e instanceof ServletException) {
throw (ServletException)e;
}
if (e instanceof IOException) {
throw (IOException)e;
}
if (e instanceof RuntimeException) {
throw (RuntimeException)e;
}
throw new ServletException(e.getMessage(), e);
}
} else {
this.internalDoFilter(request, response);
}
}
FilterChain 就是一条过滤链。其中每个过滤器(Filter)都可以决定是否执行下一步。过滤分两个方向,进和出:
进:在把ServletRequest和ServletResponse交给Servlet的service方法之前,需要进行过滤
出:在service方法完成后,往客户端发送之前,需要进行过滤
Spring MVC 的 diapatcherServlet 的 doDispatch 方法中,获取与请求匹配的处理器 HandlerExecutionChain
就是用到了责任链模式。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null; //使用到了责任链模式
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
//责任链模式执行预处理方法,其实是将请求交给注册的拦截器执行
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
//责任链执行后处理方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var22) {
//...
} finally {
}
}
责任链模式其实就是一个灵活版的 if…else…语句,它就是将这些判定条件的语句放到了各个处理类中,这样做的优点是比较灵活了,但同样也带来了风险,比如设置处理类前后关系时,一定要特别仔细,搞对处理类前后逻辑的条件判断关系,并且注意不要在链中出现循环引用的问题。
优点:
缺点:
使用场景:
模式的扩展:
职责链模式存在以下两种情况。
《研磨设计模式》
https://wiki.jikexueyuan.com/project/java-design-pattern/chain-responsibility-pattern.html
https://refactoringguru.cn/design-patterns/chain-of-responsibility
标签:ring patch actor proc strong test factor cep rgs
原文地址:https://www.cnblogs.com/lazyegg/p/12696157.html