• 设计模式--责任链模式


    一、什么是责任链?

    「责任链模式」 是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
    在这里插入图片描述

    二、如果不用责任链模式会怎么样?

    这里我举个例子说明下‘’

    假设现在有一个闯关游戏,进入下一关的条件是上一关的分数要高于xx

    1、 游戏一共3个关卡;
    2、 进入第二关需要第一关的游戏得分大于等于80;
    3、 进入第三关需要第二关的游戏得分大于等于90;

    代码如下:

    //第一关
    public class FirstPassHandler {
        public int handler(){
            System.out.println("第一关-->FirstPassHandler");
            return 80;
        }
    }
    
    //第二关
    public class SecondPassHandler {
        public int handler(){
            System.out.println("第二关-->SecondPassHandler");
            return 90;
        }
    }
    //第三关
    public class ThirdPassHandler {
        public int handler(){
            System.out.println("第三关-->ThirdPassHandler,这是最后一关啦");
            return 95;
        }
    }
    
    //客户端
    public class HandlerClient {
        public static void main(String[] args) {
    
            FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
            SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
            ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关
    
            int firstScore = firstPassHandler.handler();
            //第一关的分数大于等于80则进入第二关
            if(firstScore >= 80){
                int secondScore = secondPassHandler.handler();
                //第二关的分数大于等于90则进入第二关
                if(secondScore >= 90){
                    thirdPassHandler.handler();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    那么如果这个游戏有100关,我们的代码很可能就会写成这个样子

    if(1关通过){
        // 第2关 游戏
        if(2关通过){
            // 第3关 游戏
            if(3关通过){
               // 第4关 游戏
                if(4关通过){
                    // 第5关 游戏
                    if(5关通过){
                        // 第6关 游戏
                        if(6关通过){
                            //...
                        }
                    }
                } 
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这种代码不仅冗余,并且当我们要将某两关进行调整时会对代码非常大的改动,这种操作的风险是很高的,因此,该写法非常糟糕

    三、使用责任链改造

    • 既然每个关卡中都有下一关的 成员变量并且是不一样的,那么我们可以在关卡上抽象出一个父类或者接口,然后每个具体的关卡去继承或者实现

    有了思路,我们先来简单介绍一下责任链设计模式的「基本组成」

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

    在这里插入图片描述
    代码如下:

    public abstract class AbstractHandler {
    
        /**
         * 下一关用当前抽象类来接收
         */
        protected AbstractHandler next;
    
        public void setNext(AbstractHandler next) {
            this.next = next;
        }
    
        public abstract int handler();
    }
    
    public class FirstPassHandler extends AbstractHandler{
    
        private int play(){
            return 80;
        }
    
        @Override
        public int handler(){
            System.out.println("第一关-->FirstPassHandler");
            int score = play();
            if(score >= 80){
                //分数>=80 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
            return score;
        }
    }
    
    public class SecondPassHandler extends AbstractHandler{
    
        private int play(){
            return 90;
        }
    
        public int handler(){
            System.out.println("第二关-->SecondPassHandler");
    
            int score = play();
            if(score >= 90){
                //分数>=90 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
    
            return score;
        }
    }
    
    public class ThirdPassHandler extends AbstractHandler{
    
        private int play(){
            return 95;
        }
    
        public int handler(){
            System.out.println("第三关-->ThirdPassHandler");
            int score = play();
            if(score >= 95){
                //分数>=95 并且存在下一关才进入下一关
                if(this.next != null){
                    return this.next.handler();
                }
            }
            return score;
        }
    }
    
    public class HandlerClient {
        public static void main(String[] args) {
    
            FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
            SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
            ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关
    
            // 和上面没有更改的客户端代码相比,只有这里的set方法发生变化,其他都是一样的
            firstPassHandler.setNext(secondPassHandler);//第一关的下一关是第二关
            secondPassHandler.setNext(thirdPassHandler);//第二关的下一关是第三关
    
            //说明:因为第三关是最后一关,因此没有下一关
    
            //从第一个关卡开始
            firstPassHandler.handler();
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
  • 相关阅读:
    创业前3年公司死亡率高达95%!如何提升成功率?
    Android与H5交互 -- 点击H5跳转到 Android原生 页面
    / 将 Month 转换为整数:int monthAsInt = static_cast<int>(month);“static_cast”是干啥的?
    让直播和视频通话更精彩的实时换脸神器: 亲妈都未必认识
    内网服务器无法访问外网下载时,制作本地清华镜像源,搭建中转服务器(rinted)
    【人工智能】本地运行开源项目MMSegmentation引发的问题
    AIGC:python 文生图代码(python + stable-diffusion+ cuda)
    面试中的压力测试:如何稳定自己的心态
    把Stream流学透了你也能写出简洁高效的代码,来看看吧(建议收藏)
    allure-日志模块级别控制
  • 原文地址:https://blog.csdn.net/qq_40241957/article/details/125461040