概述

概念:责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

意图及组成

责任链的意图是给多个对象赋予请求的权利,从而解耦发送者和接受者,该请求链对象会在一条链上一直传递直到其中有对象处理它,一个简单的模型如下:

责任链模式_设计模式


而在实际情况中可能会多次流转,直到找到处理对象。

责任链模式_对象_02


责任链模式的结构主要包括Handler、ConcreteHandler和Client三部分。在责任链模式中Client像Handler提交请求,请求在多个ConcreteHandler对象形成的对象链中传递,直到该请求被处理。

  • Handler(抽象处理者角色):定义出一个处理请求的接口。实现后继链。
  • ConcreteHandler(具体处理者角色):处理它所负责的请求。可以访问它的后继者。如果可以处理该请求就处理。
  • Client:客户端像链上的具体处理对象提交请求。

代码实例

抽象处理者角色

public abstract class Handler
protected Handler successor;
public abstract void handleRequest();

public Handler getSuccessor() {
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}

具体处理者角色

public class ConcreteHandler extends Handler

@Override
public void handleRequest() {

if(getSuccessor() != null)
{
System.out.println("放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("处理请求");
}
}
}

客户端

public class Client {

public static void main(String[] args) {
//组装责任链
Handler handler1 = new ConcreteHandler();
Handler handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
//提交请求

可以看出,客户端创建了两个处理者对象,并指定第一个处理者对象的下家是第二个处理者对象,而第二个处理者对象没有下家。然后客户端将请求传递给第一个处理者对象。

使用场景

在以下情况下可以考虑使用责任链模式:
1、处理者在运行时动态确定其实是我们在 Client 中组装的链所引起的,因为具体的职责逻辑就在链中一一对应起来;
2、因为不确定请求的具体处理者是谁,所以我们把所有可能的处理者组装成一条链,在遍历的过程中就相当于向每个处理者都提交了这个请求,等待其审查。并且在审查过程中,即使不是最终处理者,也可以进行一些请求的“包装”操作(这种功能类似于装饰者模式),例如上面例子中的签名批准;
3、处理者集合的动态指定跟上面的第1、2点类似,即在 Client 类中创建了所有可能的处理者。

不足之处

1、对于每一个请求都需要遍历职责链,性能是个问题;
2、抽象处理者 AbstractHandler 类中的 handleRequest() 方法中使用了递归,栈空间的大小也是个问题。