设计模式太难学?Java设计模式之责任链模式


前言

责任链模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

责任链模式又叫职责链模式,它是行为型设计模式中的一种。该模式通过创建一组对象,对象之间依次引用,形成一条对象链。适用于可能需要多个对象处理的事件场景。

在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。比如:OA系统的流程审批,一个采购审批可能因为采购金额的变化而使得流程审批人也有相应变化。采购金额1万元之内需要一级审批人审批、大于1万元需要二级审批人审批、大于10万元需要三级审批人审批!

这种场景就可以使用责任链模式。创建一组流程审批人处理对象,根据审批等级依次往下,形成一条审批责任链
图示(来源网络):
在这里插入图片描述
除了上面说的流程审批,我们平时web开发中的过滤器、Netty框架中用到的pipline管道都是采用责任链模式设计的。


一、责任链模式

责任链模式的结构角色为:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。(责任链可以事先定义好链路,也可以先声明对象处理组,客户端调用时自定义链表顺序)

结构角色图示(来源网络):
在这里插入图片描述
该图示说明:创建一个抽象的对象处理类,实际对象处理由子类继承实现。客户端通过该抽象类编程,可自定义处理顺序。

二、责任链模式使用

以上面的审批流程为例,下面介绍一下责任链模式的使用

首先定义抽象处理者对象类

package com.example.study.responsibilityChain;

public abstract class Handler {

    private Handler next;

    public Handler getNext() {
        return next;
    }

    public void setNext(Handler next) {
        this.next = next;
    }

    //处理请求的方法
    public abstract void handleRequest(Integer request);
}

抽象实现类
一级审批

package com.example.study.responsibilityChain;

public class OneHandlerImpl extends Handler{
    @Override
    public void handleRequest(Integer request) {
        if (request < 10000){
            System.out.println("1万元以内,一级审批通过");
            return;
        }
        getNext().handleRequest(request);
    }
}

二级审批

package com.example.study.responsibilityChain;

public class TwoHandlerImpl extends Handler{
    @Override
    public void handleRequest(Integer request) {
        if (request < 100000){
            System.out.println("10万元以内,二级审批通过");
            return;
        }
        getNext().handleRequest(request);
    }
}

三级审批

package com.example.study.responsibilityChain;

public class ThreeHandlerImpl extends Handler{
    @Override
    public void handleRequest(Integer request) {
        if (request >= 100000){
            System.out.println("大于或等于10万元,三级审批通过");
            return;
        }
        getNext().handleRequest(request);
    }
}

客户端类

package com.example.study.responsibilityChain;

public class Client {

    public static void main(String[] args) {
        //创建对象处理组
        Handler oneHandler = new OneHandlerImpl();
        Handler twoHandler = new TwoHandlerImpl();
        Handler threeHandler = new ThreeHandlerImpl();
        //构建责任链
        oneHandler.setNext(twoHandler);
        twoHandler.setNext(threeHandler);

        //5000一级审批
        oneHandler.handleRequest(5000);
        //50000二级审批
        oneHandler.handleRequest(50000);
        //110000三级审批
        oneHandler.handleRequest(110000);
    }
}

运行结果:
在这里插入图片描述

总结

责任链模式其主要优点如下。

  • 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
  • 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
  • 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
  • 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
  • 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

其主要缺点如下。

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值