1.概念
为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。
这里解耦的意思是,我们在一般的处理里,是根据请求,去选择处理的对象,例如:请求A,通过逻辑判断,选择B对象去处理,请求C,通过逻辑判断,选择D对象处理。这样做,就是把请求的判断和处理,写在一起了,耦合度较高。责任链的思想就是,把这些逻辑判断,形成一条链,请求只管往链上扔,判断的逻辑,由这条链来处理。链上的每个节点判断是否处理这个请求,如果处理,则调用这个节点的处理方法,如果不处理,则进入下一个节点进行判断。这样就把发送者和处理者解耦合了。
2.角色
抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。创建处理链的意思就是,客户端决定这个链的顺序是谁先谁后。这是标准模式,在实际应用中,实现方式会千变万化,核心思想不变就是责任链模式。
3.代码实现
首先,我们实现抽象处理者角色,抽象处理者是责任链的核心,其主要包括下一个节点的成员属性和抽象的处理方法,代码如下:
/**
* 抽象处理者,定义下一个节点和处理方法。
* 下一个节点,便于形成责任链,当该对象不处理请求时,走到下一个节点
* 处理方法,供不同的责任链,实现不同的处理方式
*/
public abstract class Handler {
//指向下一个节点
private Handler next;
public void setNext(Handler next){
this.next=next;
}
public Handler getNext(){
return next;
}
//处理方法
public abstract void handleRequest(String request);
}
然后,我们定义具体的处理者,代码如下:
/**
* 具体处理者,实现处理方法,主要逻辑就是判断是否处理该请求,如果处理,则进行处理,如果不处理,则放行到下一个节点
*/
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String request) {
if(request.equals("one"))
{
System.out.println("具体处理者1负责处理该请求!");
}
else
{
if(getNext()!=null)
{
getNext().handleRequest(request);
}
else
{
System.out.println("没有人处理该请求!");
}
}
}
}
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String request) {
if(request.equals("two"))
{
System.out.println("具体处理者2负责处理该请求!");
}
else
{
if(getNext()!=null)
{
getNext().handleRequest(request);
}
else
{
System.out.println("没有人处理该请求!");
}
}
}
}
客户端调用责任链,将请求传入责任链,让责任链进行处理:
public class ChainOfResponsibilityPattern
{
public static void main(String[] args)
{
//组装责任链
Handler handler1=new ConcreteHandler1();
Handler handler2=new ConcreteHandler2();
handler1.setNext(handler2);
//提交请求
handler1.handleRequest("two");
}
}
当我们添加处理者时,只要实现抽象处理者接口,然后在客户端,将新的处理者加入责任链中,即可。
4.责任链模式的应用
Tomcat的过滤器,使用了责任链模式,这里我们先不过多讲解,以后我会出Tomcat源码分析文章,我们在那里见哦😊😊😊