Java设计模式之责任链模式

责任链模式是一种处理请求的模式,允许多个处理器按顺序处理请求。本文通过员工请假的例子解释了如何实现责任链,并展示了在Android View事件传递中的应用。此外,还详细介绍了OkHttp中利用责任链模式处理请求的流程,如拦截器的使用,以及其优缺点。通过对OkHttp拦截器的理解,可以看到责任链模式在实际开发中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

责任链模式是一种处理请求的模式,该模式会把多个处理器添加到一个处理器数组(或者通过链表串成一条链),从而使得多个处理器都有机会处理请求。如果当前处理器成功处理请求,会直接返回结果,否则会把当前请求传递给下一个处理器。

当你想要让一个以上的处理器有机会能够处理某个请求的时候,就使用责任链模式。(Chain of Responsibility Pattern) — 引自Head First

责任链.png

  • Client:客户端
  • Handler:抽象处理者
  • ConcreteHandler:具体处理者

使用举例

以员工请假为例子,假设员工小强要请假,制度如下:

  • 组长可以审批3天之内的假期(包括3天)
  • 部门主管可以审批7天之内的假期(包含7天)
  • CEO可以审批任何时间之内的假期

请求Request:

public class Request {

    private int num;//请假天数

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

处理器Handler:

//声明处理器接口
public interface Handler {
    boolean process(Request request);
}

//具体处理器(组长AHandler)
public class AHandler implements Handler {

    @Override
    public boolean process(Request request) {

        if (request.getNum() < 3) {
            System.out.println("AHandler(组长)处理了该请假申请");
            return true;
        }
        System.out.println("AHandler(组长)处理不了该申请,往下传递");
        return false;
    }
}

//具体处理器(部门主管BHandler)
public class BHandler implements Handler {

    @Override
    public boolean process(Request request) {

        if (request.getNum() < 7) {
            System.out.println("BHandler(部门主管)处理了该请假申请");
            return true;
        }
        System.out.println("BHandler(部门主管)处理不了该申请,往下传递");
        return false;
    }
}

//具体处理器(CEO CHandler)
public class CHandler implements Handler {

    @Override
    public boolean process(Request request) {

        System.out.println("CHandler(CEO)处理了该请假申请");
        return true;
    }
}

处理链Chain:

public class HandlerChain {

    private List<Handler> chains = new ArrayList<>();

    public void addHandler(Handler handler) {
        chains.add(handler);
    }

    public boolean process(Request request) {
        //遍历链中处理器队请求进行处理
        for (Handler handler : chains) {
            boolean isHandled = handler.process(request);
            //如果该处理器成功处理请求,直接返回
            if (isHandled) {
                return true;
            }
        }
        System.out.println("都处理不了了");
        return false;
    }
}

如果请假天数为5天:

public static void main(String[] args) {
    HandlerChain chain = new HandlerChain();
    chain.addHandler(new AHandler());
    chain.addHandler(new BHandler());
    chain.addHandler(new CHandler());

    int requestDay = 5;
    Request request = new Request();
    request.setNum(requestDay);
    System.out.println("请求假期天数为:" + requestDay);
    chain.process(request);
}

执行结果:

请求假期天数为:5
AHandler(组长)处理不了该申请,往下传递
BHandler(部门主管)处理了该请假申请

如果将请假天数改为30,即将上述代码中修改为int requestDay = 30;,从新执行:

请求假期天数为:30
AHandler(组长)处理不了该申请,往下传递
BHandler(部门主管)处理不了该申请,往下传递
CHandler(CEO)处理了该请假申请

责任链模式在Android中的使用

View事件传递

事件传递.png

伪代码表示dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三者之间的关系:

public boolean dispatchTouchEvent (MotionEvent ev){
    boolean consume = false;
    if (onInterceptTouchEvent(ev)) {
        consume = onTouchEvent(ev);
    } else {
        consume = child.dispatchTouchEvent(ev);
    }
    return consume;
}

View事件传递也可以认为是一种责任链模式,使得参与的View或者ViewGroup都有机会去处理TouchEvent。

OkHttp

OkHttp中的处理器(拦截器)主要有下面几个:

  • 自定义interceptor: 开发者在配置 OkHttpClient时设置;
  • RetryAndFollowUpInterceptor: 负责失败重试以及重定向;
  • BridgeInterceptor: 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应;
  • CacheInterceptor: 负责读取缓存直接返回、更新缓存;
  • ConnectInterceptor: 负责和服务器建立连接;
  • networkInterceptors: 配置 OkHttpClient 时设置的;
  • CallServerInterceptor: 负责向服务器发送请求数据、从服务器读取响应数据。

OkHttp中的责任链模式,每个Handler处理器(拦截器)都有机会去处理Request,这种处理器更适合称为拦截器(Interceptor),它的目的不是找到某个Handler处理掉Request,而是每个Handler都对Request做一些工作。

优缺点

优点

  • 将请求的发送者和接受者进行解耦,请求者不需要知道链表的存在
  • 通过改变链内的成员或调动它们的次序,允许动态地新增或删除责任。

缺点

  • 并不能保证请求一定会执行,如果没有任何责任链中的对象处理请求的话,请求可能会落到链表的尾端之外(可以新增一个终端处理)。
  • 不容易观察运行时的特征,不容易除错。

参考

【1】https://www.liaoxuefeng.com/wiki/1252599548343744/1281319474561057
【2】https://blog.youkuaiyun.com/gdutxiaoxu/article/details/100189121
【3】Android中的责任链模式分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小马快跑_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值