简述
责任链模式是一种处理请求设计模式,属于行为设计模式。它允许多个处理器都有机会处理请求,直到某个请求被处理为止。责任链模式把多个处理器串成链,让请求在链上传递。
优缺点
优点
- 使得请求的发送者和处理者解藕。
- 添加新的处理者或者重新排列处理者的时候很容易。
- 可以控制处理者的顺序。
缺点
- 部分请求可能会没有被处理。
责任链模式的结构
- 处理者的基类:可以将所有处理者共用操作在这里处理。可以定义为不可修改,保存对下个处理者的成员变量。
- 具体处理者的实现类:每个处理者有自己的处理逻辑。也可以不处理本次请求,交给下一个处理者处理。
- 请求类:需要发送的请求类,一般结合建造者设计模式使用。
- 链条:将所有的处理者串成一个链条,让每个处理者都有机会处理请求。
应用场景
- 当程序需要使用不同方式处理不同种类的请求,请求类型和顺序预先未知。例如报销审批模式,当0-100额度,自动发送给 A 审批,100-200自动发送给 B 审批等等(这里可以通过A 也可以不通过A)
- 当请求必须按顺序执行时。比如请假审批模式,请假必须先经过直属lead审批,再经过部门经理审批,最后发送HR审批。
- 每个处理者分别处理给自请求,互不影响。比如订购系统,记录日志、检查权限、准备相关资源…这种一般是拦截器、过滤器,例如 OKHttp 源码里使用到的拦截器。
代码实现
-
基础处理类:放置处理者公共逻辑,比如声明下一个处理者的成员变量。
java">public abstract class BaseHandler implements IHandler { protected BaseHandler mNextHandler; @Override public void nextHandler(BaseHandler handler) { this.mNextHandler = handler; } }
-
处理者的接口:定义需要实现的方法
java">public interface IHandler { void nextHandler(BaseHandler handler); Result prosseed(Request params); }
-
具体的处理者:处理请求或者将请求发送给下一个处理者
java">public class Handler extends BaseHandler implements IHandler { @Override public void nextHandler(BaseHandler handler) { mNextHandler = handler; } @Override public Result prosseed(Request params) { // 这里处理逻辑,如果不处理,约定好返回 null 则交给下一个处理 return null; } } // 第二个处理者 public class BHandler extends BaseHandler implements IHandler { @Override public Result prosseed(Request params) { if (params.getName().equalsIgnoreCase("params")) { Result result = new Result(); result.setResponse("result"); return result; } return null; } }
-
将处理者串成链条:让每个处理者都有机会处理请求
java">public class HandlerChain { private List<BaseHandler> handlers = new ArrayList<>(); public void addHandler(BaseHandler handler) { handlers.add(handler); } public Result procees(Request request) throws IllegalAccessException { for (BaseHandler handler : handlers) { return handler.prosseed(request); } throw new IllegalAccessException("Can not handle request"); } }
-
定义请求者和结果(一般结合建造者模式)
java">class Request { // 可以对请求类进行扩展。一般结合建造者使用 private String name; private String version; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } } class Result { // 可以对结果类进行扩展 private String response; public String getResponse() { return response; } public void setResponse(String response) { this.response = response; } }