二十三种设计模式(二十三)--责任链模式

责任链模式(Chain of Responsibility)

责任链模式处理同样的任务但是分多个等级去做不同的应对的问题

只要出现多个对象处理的是同一个请求, 并且这多个对象是有顺序有条件的去应对请求的, 就要使用责任链模式.

假设我们有一支军队, 我军按照不同的规模编排队伍中人数的大小, 分别是军, 师, 旅, 团四种规模

四种规模的军队分别抵抗和我军人数相当的敌军规模

为了满足这个需求, 代码实现如下:

java 复制代码
abstract class MilUnit {
    int enemyForces;

    MilUnit nextUnit; // 用来指向责任链的下一环

    abstract void attack(int enemyForces);

    // 责任链的下一环由业务逻辑决定
    void setNext(MilUnit unit) {
        this.nextUnit = unit;
    }
}

class JunUnit extends MilUnit {
    @Override
    public void attack(int enemyForces) {
        System.out.println("[进攻] 211集团军战士冲上前线, 军长彭大帅");
    }
}

class ShiUnit extends MilUnit {
    @Override
    public void attack(int enemyForces) {
        if (enemyForces >= 10000 && enemyForces <= 20000) {
            System.out.println("[进攻] 34师战士冲上前线, 师长李云龙");
        } else {
            System.out.println("[撤退] 请求军长支援");
            nextUnit.attack(enemyForces);
        }

    }
}

class LvUnit extends MilUnit {
    @Override
    public void attack(int enemyForces) {
        if (enemyForces >= 3000 && enemyForces < 10000) {
            System.out.println("[进攻] 17旅战士冲上前线, 旅长黄小琥");
        } else {
            System.out.println("[撤退] 请求师长支援");
            nextUnit.attack(enemyForces);
        }
    }
}

class TuanUnit extends MilUnit {
    @Override
    public void attack(int enemyForces) {
        if (enemyForces < 3000) {
            System.out.println("[进攻] 3团战士冲上前线, 团长王小二");
        } else {
            System.out.println("[撤退] 请求旅长支援");
            nextUnit.attack(enemyForces);
        }

    }
}

如上代码就是一个简单的责任链模式实现, 输入量为敌军人数,

我军通过敌军人数去判断不同的作战单位去迎战

现实中有很多类似的需求, 比如办公请假审批制度, 请假人数在个位数时, 人事直接处理, 在10-20人时, 小组长负责审批, 请假人数在20-50人时, 项目经理负责审批, 大于50人时, 老板负责审批

总结特点就是, 每个人所做的操作都是一样的, 就是审批, 上述代码中的案例, 相同的动作则是进攻

然后责任链模式中, 在进攻方法中, 要判断当前敌人的数量, 超出本单位所能承受的范围时, 就将任务交给下一级别的单位去执行

调用逻辑如下:

java 复制代码
public class Responsibility {
    public static void main(String[] args) {
        MilUnit jun = new JunUnit();
        MilUnit shi = new ShiUnit();
        MilUnit lv  = new LvUnit();
        MilUnit tuan = new TuanUnit();

        // 这里设置责任链的起点为团, 终点为军, 逐级迎战
        tuan.setNext(lv);
        lv.setNext(shi);
        shi.setNext(jun);

        System.out.println("===== 第一波敌军规模200人");
        tuan.attack(200);
        System.out.println("===== 第二波敌军规模4000人");
        tuan.attack(4000);
        System.out.println("===== 第三波敌军规模15000人");
        tuan.attack(15000);
        System.out.println("===== 第五波敌军规模50000人");
        tuan.attack(50000);

    }
}

输出:

复制代码
===== 第一波敌军规模200人
[进攻] 3团战士冲上前线, 团长王小二
===== 第二波敌军规模4000人
[撤退] 请求旅长支援
[进攻] 17旅战士冲上前线, 旅长黄小琥
===== 第三波敌军规模15000人
[撤退] 请求旅长支援
[撤退] 请求师长支援
[进攻] 34师战士冲上前线, 师长李云龙
===== 第五波敌军规模50000人
[撤退] 请求旅长支援
[撤退] 请求师长支援
[撤退] 请求军长支援
[进攻] 211集团军战士冲上前线, 军长彭大帅

调用时先实例化执行动作的各个单元, 它们之间默认没有相互联系

然后通过setNext方法将它们的先后顺序串联起来

实际处理业务时, 都是从通过责任链的开头去应对所有数量的敌人

这里有个缺陷就是责任链的每一环都是暴露在外的, 如果调用者没有直接从责任链开头TuanUnit开始调用, 而是直接调用JunUnit去处理所有问题, 那么这个责任链模式将失效, 所以实际业务中, 要将这部分封装起来, 只暴露责任链开头.

相关推荐
自在极意功。17 小时前
简单介绍SpringAOP
java·spring·aop思想
TT哇17 小时前
基础的IDEA基本使用,如:debug流程、常用快捷键
java·ide·intellij-idea
梵得儿SHI17 小时前
(第七篇)Spring AI 核心技术攻坚:国内模型深度集成与国产化 AI 应用实战指南
java·人工智能·spring·springai框架·国产化it生态·主流大模型的集成方案·麒麟系统部署调优
北辰当尹17 小时前
【实习之旅】Kali虚拟机桥接模式ping通百度
java·服务器·桥接模式
Just Dreamchaser17 小时前
Pdf和Docx文件导出生成水印工具类
java·给pdf和docx文件添加水印
这个需求做不了18 小时前
Java实现文件格式转换(图片,视频,文档,音频)
java
愿你天黑有灯下雨有伞18 小时前
高性能Java并发编程:如何优雅地使用CompletableFuture进行异步编排
java
indexsunny18 小时前
互联网大厂Java面试实战:基于电商场景的Spring Boot与微服务技术问答
java·spring boot·微服务·面试·hibernate·电商场景·技术问答
qq_124987075318 小时前
基于Spring Boot的电影票网上购票系统的设计与实现(源码+论文+部署+安装)
java·大数据·spring boot·后端·spring·毕业设计·计算机毕业设计