责任链模式属于设计模式中的行为型设计模式。如果存在多个对象可以处理同一请求,则可以通过责任链模式将这些处理请求的处理者连成一条链,让请求沿着该链进行传递。如果链上的处理者可以处理该请求那么就进行处理,否则将请求转发给下家来处理。责任链模式可以将请求的发送者和接收者解耦,客户端无须关心请求的处理细节和传递过程,只需要将请求提交给这个处理请求链即可。
责任链可以是一条直线、一个环或者一个树形结构,最常见的责任链是直线型,即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者。
(1)Handler(抽象处理者)
(2)ConcreteHandler(具体处理者)
(3)Client(客户端,即使用责任链模式的地方)
下面我们就以一个公司的费用报销流程为例,来看一下责任链模式的实现。
一个公司的员工为公司购买设备花去了一定的费用,然后提交报销。而报销是有一个报销流程,需要层层审批。
(1)如果报销费用金额小于500,Leader就可以直接做主,给你审批通过;
(2)如果报销费用金额大于500且小于5000,那么Manager就能给你审批通过;
(3)如果报销费用金额大于5000且小于5000,那么Boss就能给你审批通过;
(4)如果报销费用金额大于50000,由于报销金额太大,需要董事会的审批。
/**
* 抽象处理类
*/
public abstract class Person {
protected Person person;
public void setPerson(Person person){
this.person=person;
}
/**
* 报销费用
* @param amount 报销金额
*/
public abstract void expenseReimbursement(int amount);
}
/**
* 具体处理者 Leader
*/
public class Leader extends Person {
@Override
public void expenseReimbursement(int amount) {
if (amount<500){
Log.e("========","===没问题,小意思,Leader给你报销,就不麻烦后面的领导了");
}else{
Log.e("========","=======我是个小Leader,你这超过500了,金额太大,还是交给后面的大领导给你审批吧");
person.expenseReimbursement(amount);
}
}
}
/**
* 具体处理者 Manager
*/
public class Manager extends Person {
@Override
public void expenseReimbursement(int amount) {
if (amount<5000){
Log.e("========","===没问题,小意思,Manager给你报销,就不麻烦后面的领导了");
}else{
Log.e("========","=======我是个小Manager,你这超过5000了,金额太大,还是交给后面的大领导给你审批吧");
person.expenseReimbursement(amount);
}
}
}
/**
* 具体处理者 Boss
*/
public class Boss extends Person {
@Override
public void expenseReimbursement(int amount) {
if (amount<50000){
Log.e("========","===没问题,小意思,Boss给你报销");
}else{
Log.e("========","=======我是个小Boss,你这超过50000了,金额太大了,还是交给董事会审批吧");
if (person!=null){
person.expenseReimbursement(amount);//转发请求
}
}
}
}
public class TestDutyLink {
public static void main(String[] args) {
//创建处理者对象
Person leader=new Leader();
Person manager=new Manager();
Person boss=new Boss();
//创建处理者的责任链
leader.setPerson(manager);
manager.setPerson(boss);
//发送请求
leader.expenseReimbursement(300);
leader.expenseReimbursement(3000);
leader.expenseReimbursement(30000);
leader.expenseReimbursement(300000);
}
}
责任链设计模式可以分为纯的责任链模式和不纯的责任链模式
(1)纯的责任链模式
一个纯的责任链模式要求一个具体处理者对象只能在两个行为中选择一个,要么承担全部责任,要么将责任推给下家,不允许出现某一个具体处理者对象在承担了一部分或全部责任后又将责任向下传递的情况。而且纯的责任链模式中要求一个请求必须被某一个处理者对象所接收,不能出现某个请求未被任何一个处理者对象处理的情况。
(2)不纯的责任链模式
在一个不纯的职责链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后,其后继的处理者可以继续处理该请求,而且一个请求可以最终不被任何处理者对象所接收并处理。
我们所见到的基本都是不纯的责任链。
(1)职责链模式使得一个对象无须知道是哪一个处理者处理了请求,对象仅需知道请求会被处理即可,由客户端负责链的创建,降低了耦合度。
(2)增加一个新的具体处理者无需修改原有的代码,只需要在客户端重新建链即可,从这一点来看是符合开放封闭原则的。
(1)由于一个请求没有明确的处理者,那么就不能保证它一定会被处理,该请求有可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理
(2)对于比较长的职责链,请求的处理可能涉及多个对象,系统性能将受到一定的影响,而且在进行代码调试时不方便。
(3)如果建链不当,可能会造成循环调用,将导致系统陷入死循环。
(1)有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无需关心请求的处理对象是谁以及它是如何处理的。
(2)在不明确指定接收者的情况下向多个对象中的一个提交请求
(3)可动态指定一组对象的处理请求,客户端可以动态创建责任链来处理请求,还可以改变链中处理者之间的先后次序。
Android中常见的应用了责任链模式的地方:
(1)事件分发机制
(2)OkHttp中的拦截器用到了责任链模式