责任链模式
定义
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
责任链模式示意图
流程
定义一个请求以及这个请求对应的处理器标识。
创建一个抽象处理器,用来封装所有处理器的相同部分,所有实体处理器都要继承这个抽象类。
我们定义的请求会访问抽象处理器(使用多态),所有的处理器组成一个责任链条,我们的请求会从责任链条头部一个个节点的比对处理器标识,如果处理器标识比对成功,就获取对应处理器。
获取到对应处理器后,处理器就开始响应这个请求。
代码实现
处理器
Handler(抽象处理器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package org.example.chain;public abstract class Handler { public final static int GET_REQUEST = 0 ; public final static int POST_REQUEST = 1 ; public final static int OTHER_REQUEST = 2 ; private int handlerCount = 0 ; private Handler nextHandler ; private int level ; public Handler (int level) { this .level = level ; } public void handlerMessage (Request request) { if (this .level == request.getType()){ this .response(request); }else { if (nextHandler != null ){ this .nextHandler.handlerMessage(request); }else { System.out.println("没有适合的处理器处理请求。" ); } } } public void setNextHandler (Handler handler) { if (handlerCount < 5 ){ this .nextHandler = handler ; handlerCount++ ; }else { System.out.println("责任链条超出阈值" ); } } protected abstract void response (Request request) ; }
GetHandler(get请求处理器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package org.example.chain;public class GetHandler extends Handler { public GetHandler () { super (Handler.GET_REQUEST); } @Override protected void response (Request request) { System.out.println("开始处理GET请求:" +request.getRequest()); } }
PostHandler(post请求处理器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package org.example.chain;public class PostHandler extends Handler { public PostHandler () { super (Handler.POST_REQUEST); } @Override protected void response (Request request) { System.out.println("开始处理POST请求:" +request.getRequest()); } }
OtherHandler(其他请求处理器)
1 2 3 4 5 6 7 8 9 10 11 package org.example.chain;public class OtherHandler extends Handler { public OtherHandler () { super (Handler.OTHER_REQUEST); } @Override protected void response (Request request) { System.out.println("开始处理其他请求:" +request.getRequest()); } }
请求
Request(请求实体)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package org.example.chain;public class Request { private int type ; private String request ; public Request (int type , String request) { this .type = type ; switch (type){ case 0 : this .request = request+"是一个GET请求" ; break ; case 1 : this .request = request+"是一个POST请求" ; break ; case 2 : this .request = request+"是一个未知请求" ; break ; } } public int getType () { return this .type ; } public String getRequest () { return this .request ; } }
场景实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class App { public static void main (String[] args) { Request request = new Request(0 , "http://example.com/get?a=b" ); Request request1 = new Request(1 , "http://example.com/post" ); Request request2 = new Request(2 , "http://example.com/other" ); GetHandler getHandler = new GetHandler(); PostHandler postHandler = new PostHandler(); OtherHandler otherHandler = new OtherHandler(); getHandler.setNextHandler(postHandler); postHandler.setNextHandler(otherHandler); getHandler.handlerMessage(request); getHandler.handlerMessage(request1); getHandler.handlerMessage(request2); } }
应用场景
责任链模式的优缺点
优点
将请求和处理分开,两者解耦。
缺点
性能问题。每次请求都要从头开始遍历,如果请求匹配的处理器都是在末尾,非常耗费性能。
调试不方便。采用了递归方式,调试时逻辑比较复杂。
注意事项
责任链中的节点需要控制数量,责任链不能太长。一般做法是在抽象处理器中设置责任链最大节点数。