浅析设计模式5 -- 责任链模式(上)

简介: 浅析设计模式5 -- 责任链模式(上)




我们在进行软件开发时要想实现可维护、可扩展,就需要尽量复用代码,并且降低代码的耦合度。设计模式就是一种可以提高代码可复用性、可维护性、可扩展性以及可读性的解决方案。大家熟知的23种设计模式,可以分为创建型模式、结构型模式和行为型模式三大类。本专题着眼于实际开发过程中常用的几种设计模式,从理论和实战两个角度进行讨论和分享,力求逻辑清晰、表述简洁,帮助大家在项目中合理运用设计模式,保障代码的可靠性。

本文为此系列第五篇文章,前四篇见——

第一篇:浅析设计模式1 —— 工厂模式

第二篇:浅析设计模式2 —— 策略模式

第三篇:浅析设计模式3 —— 装饰者模式

第四篇:浅析设计模式4——模板方法模式


概述


我们在进行软件开发时要想实现可维护、可扩展,就需要尽量复用代码,并且降低代码的耦合度,而设计模式就是一种可以提高代码可复用性、可维护性、可扩展性以及可读性的解决方案。



大家熟知的23种设计模式,可以分为创建型模式、结构型模式和行为型模式三大类。其中,行为型模式可用于描述程序中多个类和多个对象如何协作完成复杂的任务,涉及不同对象间的职责分配、算法的抽象化。责任链模式是一种典型的行为型模式,本文将着眼于责任链模式进行学习分享,阐述责任链模式的核心概念和应用实践。认识和使用责任链模式,可以在开发中有效增强应用的灵活性和可扩展性。


基本概念

责任链模式的核心思想是:将请求的每个处理者都视为一个处理节点,再将这些节点连成一条链,当请求到来后便可沿着这条链进行传递,直到有节点处理它为止。这种模式可以有效避免请求发送者和请求接受者之间的耦合关系,用户只需要将请求发送到责任链上,不用关心传递过程和处理细节。

下面从模式结构和使用步骤两个方面,简单阐述责任链方法模式的基本概念。


▐  结构


责任链模式的结构也比较简单易懂,主要包含三大类:抽象处理者类、具体处理者类和客户类,抽象处理者类中首先定义好抽象方法和后继处理机制,具体的处理方法实现将在具体处理者中执行,而客户类将对所有定义的具体处理者组装成链,让请求从链头开始沿着责任链向后执行。

角色 关系 作用
抽象处理者    Handler 具体处理者的父类 定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者   Concrete Handler 抽象构件的接口实现类 实现抽象处理者的抽象处理方法,判断能否处理本次请求,如果可以则处理,否则将转交给其后继者。
客户类   Client 将具体处理者组装成责任链 创建处理链,并向链头的具体处理者提交请求,它不关心处理细节和请求的传递过程。


▐  使用

基于上述基本概念,将装饰者模式的使用步骤概括为:step1:创建抽象处理者类,定义一个抽象方法和一个指向下一处理者节点的指针 next。step2:创建具体处理者类,实现抽象处理者类中定义的抽象方法;step3:创建客户类,将各个具体处理者类组装成责任链,将请求提交给链头的具体处理者类。

使用示例


其实,大家平常接触到的各种审批流,就涉及多个审批节点,不同的审批节点负责人分别持有不同级别的审批权限。比如:请假审批流、紧急发布审批流、报销审批流等等。疫情管控时期,我们学校为了确保在校师生及其他员工的安全,会严格要求学生不能随意出入校门,如果有特殊情况如看病就医,则需在校务系统中进行申请,系统会根据学生请假出校的时长,设置不同级别的负责人进行严格审批。这一过程,用责任链模式就可以实现。


▐  代码实现


// 创建抽象处理者类,定义指向下一节点的指针和抽象处理方法public abstract class AbstractHandler {    private AbstractHandler next;    public void setNext(AbstractHandler next) {        this.next = next;    }    public AbstractHandler getNext() {        return next;    }    public abstract void handleRequest(int leaveDayNum);}
// 定义具体处理者类1:系统自动审批public class ConcreteHandler1 extends AbstractHandler {    @Override    public void handleRequest(int leaveDayNum) {        if (leaveDayNum <= 1) {            System.out.println("请假不超过" + leaveDayNum + "天" + ": 学校自动审批通过");        } else {            if (getNext() != null) {                getNext().handleRequest(leaveDayNum);            } else {                System.out.println("请假天数过长,需向学院提供签字承诺书");            }        }    }}
// 定义具体处理中类2:导师审批public class ConcreteHandler2 extends AbstractHandler {    @Override    public void handleRequest(int leaveDayNum) {        if (leaveDayNum <= 3) {            System.out.println("请假不超过" + leaveDayNum + "天" + ": 导师审批通过");        } else {            if (getNext() != null) {                getNext().handleRequest(leaveDayNum);            } else {                System.out.println("请假天数过长,需向学院提供签字承诺书");            }        }    }}
// 定义具体处理者类3:辅导员审批public class ConcreteHandler3 extends AbstractHandler {    @Override    public void handleRequest(int leaveDayNum) {        if (leaveDayNum <= 5) {            System.out.println("请假不超过" + leaveDayNum + "天" + ": 辅导员审批通过");        } else {            if (getNext() != null) {                getNext().handleRequest(leaveDayNum);            } else {                System.out.println("请假天数过长,需向学院提供签字承诺书");            }        }    }}
// 定义具体处理者类4:院长审批public class ConcreteHandler4 extends AbstractHandler {    @Override    public void handleRequest(int leaveDayNum) {        if (leaveDayNum <= 7) {            System.out.println("请假不超过" + leaveDayNum + "天" + ": 院长审批通过");        } else {            if (getNext() != null) {                getNext().handleRequest(leaveDayNum);            } else {                System.out.println("请假天数过长,需向学院提供签字承诺书");            }        }    }}
//定义客户类:组装责任链,向链头节点发送请求public class chainOfResponsibility {    public static void main(String[] args) {        AbstractHandler handler1 = new ConcreteHandler1();        AbstractHandler handler2 = new ConcreteHandler2();        AbstractHandler handler3 = new ConcreteHandler3();        AbstractHandler handler4 = new ConcreteHandler4();        handler1.setNext(handler2);        handler2.setNext(handler3);        handler3.setNext(handler4);        handler1.handleRequest(6);    }}


▐  结果输出


请假不超过6天: 院长审批通过


▐  UML图


扩展


很多文章在介绍责任链模式时都会提到一个概念:纯的责任链模式、不纯的责任链模式,这里也做一个简单的扩展。

  1. 纯的职责链模式:一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任);把责任推给下一个具体处理者处理。
  2. 不纯的职责链模式:允许出现某一个具体处理者在承担了请求的部分责任后,再将剩余责任传给下一个具体处理者继续处理剩余部分责任。


另外,在日常使用中,Handler 不是一定要提供一个设置后继处理器的接口,可以把维护链路的职责独立出来,如下图所示。



在这种责任链模式中,HandlerChain 来维护整条链路,它提供了增删处理者的方法,并实现了抽象处理者类的接口,负责在责任链中传递请求 Request。同时,HandlerChain 内部维护了当前具体处理者在整个责任链中的索引。当客户类发出请求后,HandlerChain 会驱动第一个具体处理者(pos = 0),并根据需要判断是否继续向后传递,若需要则调用 handle() 方法再次驱动下一个具体处理者(pos 在上一次驱动时自增),若不需要则跳出链路;如此反复,直到有具体处理者判断不需再向后传递,或已经执行到最后一个具体处理者。


这样,每个具体处理者不再依赖后继处理器,而是各自在 HandlerChain 中的位置 pos,从而增强模式的灵活性,解除具体处理者之间的依赖性。Servlet 中的过滤器 Filter 就是基于这种方式实现的。


更多精彩内容,欢迎观看:

浅析设计模式5 -- 责任链模式(下):https://developer.aliyun.com/article/1263228?groupCode=taobaotech

相关文章
|
设计模式 Java
【设计模式系列笔记】责任链模式
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。每个处理者都有一个对下一个处理者的引用。责任链模式常用于处理请求的场景,例如在一个请求需要经过多个步骤或者多个对象来处理的情况下。
351 0
|
设计模式 Java
【设计模式】责任链模式
【设计模式】责任链模式
121 0
|
6月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
657 2
|
7月前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
303 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
144 9
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
176 0
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
276 1
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
138 0
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
本教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速上手Kotlin的读者,推荐查阅“简洁”系列教程。本文通过学生会经费申请的例子,介绍了责任链模式及其在Kotlin中的实现,并使用偏函数进行了改进,使代码更加简洁和灵活。
123 0

热门文章

最新文章