首页 > 其他分享 >一句话设计模式5:责任链模式

一句话设计模式5:责任链模式

时间:2023-06-12 16:33:37浏览次数:37  
标签:模式 责任 tail num 链路 chainStep 设计模式 public


责任链模式:步步为营。



文章目录

  • 责任链模式:步步为营。
  • 前言
  • 一、责任链模式的作用
  • 二、如何实现责任链
  • 1 既然是责任链,那么就需要一个链路的承载体 ChainBody
  • 2 责任链中每一步都是一个抽象类,因为承载体仅仅是构造链路顺序,里面不放置任何具体业务逻辑:步骤抽象类
  • 3 具体步骤执行,继承步骤抽象类
  • 4 开始测试
  • 总结



前言

责任链模式个人认为算是设计模式中比较复杂的一个;顾名思义 责任链,这个模式的思想是: 构造一个个的,有规则的步骤,拼接为一个链路,然后执行,例如: 制作鸡蛋炒饭
第一步: 做米饭
第二步: 煎蛋
第三步: 一起炒

每一步有每一步骤的职责,当有需求改动的时候,可以灵活调整,例如我想放入葱花,那么只需要再加一步即可;


一、责任链模式的作用

旨在解决复杂业务逻辑的代码堆积化,使代码接口清晰;

1 将一个臃肿的业务逻辑,有序的拆分为多个子步骤,可以让逻辑更清晰,逻辑层代码简洁
2 多个步骤之间通常顺序不可变,但如果业务逻辑无先后顺序,也可以调整顺序,这样就会使得使用的时候,非常灵活,对于之后的业务变更等需求,扩展性非常好,扩展很简单;否则就要改动一个业务逻辑臃肿的代码,改动之前还要理清业务逻辑,而责任链方式,则只需要添加一步,甚至不用看其他代码,只要遵循已有原则,实现自己的业务逻辑就行了;
3 责任链构建好之后,当遇到同种业务逻辑,而执行顺序不同的时候,可以直接通过改变构架责任链的顺序,而快速实现编码;

二、如何实现责任链

例如: 我现在有一个数字,要加工,第一步加法 第二步减法 第三步乘法 ;每一步都有各自的处理逻辑,而且通常不会改变的部分,将他单独提取为一步,之后可能变动的,仅仅是顺序;
开始编码:

1 既然是责任链,那么就需要一个链路的承载体 ChainBody
@Data
public class ChainBody {

    private ChainStep head;

    private ChainStep tail;


    public void addChainStep(ChainStep chainStep) {

        if (null == head) {
            head = chainStep;
            tail = chainStep;
            return;
        }
        tail.setNextStep(chainStep);
        tail = chainStep;
    }

    public Integer start(Integer num) {
        if (null != head) {
            return head.handel(num);
        }
        return num;
    }
}

1 addChainStep 这个方法就是在构造一个链路,其中 tail.setNextStep(chainStep); 就在将新增加的一个步骤,作为tail这个节点的tail
2 addChainStep 这个方法中,tail一直作为head的构造子链路的一个中间变量,然后每次tail 都是最新的一个节点,为了继续构造子链路做准备
3 start 方法是为了 开始执行责任链而存在,这里面的具体执行也是交给具体步骤类执行,这里仅仅作为一个执行入口

2 责任链中每一步都是一个抽象类,因为承载体仅仅是构造链路顺序,里面不放置任何具体业务逻辑:步骤抽象类
public abstract class ChainStep {

    private ChainStep chainStep;

    public void setNextStep(ChainStep chainStep) {
        this.chainStep = chainStep;
    }

    public Integer handel(Integer num) {
        Integer res = this.doHandel(num);
        if (null != this.chainStep) {
             res = this.chainStep.handel(res);
        }
        return res;
    }

    abstract int doHandel(Integer num);
}

1 这就是步骤抽象类,setNextStep 上文已经说到
2 handel 就是入口的延续,这里作为调度具体执行步骤的一个逻辑,当有子链路的时候(tail 不为空),那么当前节点还未结束,继续执行,直到无tail后,那么执行结束,这里相当于一个递归执行
3 doHandel 是一个抽象方法,上个方法是具体步骤调度逻辑,而这个方法就是要真正的步骤类执行了,他是一个抽象方法,也就是要交给具体的步骤类去执行具体方法;

3 具体步骤执行,继承步骤抽象类
public class Step1 extends ChainStep {

    @Override
    int doHandel(Integer num) {
        return num + 5;
    }
}
public class Step2 extends ChainStep {

    @Override
    int doHandel(Integer num) {
        return num * 5;
    }
}

public class Step3 extends ChainStep {

    @Override
    int doHandel(Integer num) {
        return num - 2;
    }
}
4 开始测试
public class Test {

    public static void main(String[] args) {
        ChainBody chainBody = new ChainBody();
        chainBody.addChainStep(new Step1());
        chainBody.addChainStep(new Step2());
        chainBody.addChainStep(new Step3());
        
        //chainBody.addChainStep(new Step1());
        //chainBody.addChainStep(new Step2());
        System.out.println(chainBody.start(10));
    }
}

1 如果每个步骤里面的业务逻辑非常复杂,那么是不是这样的代码很简洁?
2 如果业务逻辑不相关,可以灵活调整执行顺序,灵活添加执行步骤

断点执行,查看责任链的链路

一句话设计模式5:责任链模式_业务逻辑


可以看到,这条完整的链路,然后根据这个链路,去递归执行;执行结果

一句话设计模式5:责任链模式_责任链模式_02


总结

责任链的难点,在于构造责任链的链路,然后做好业务抽象,将每个业务相对独立的部分单独拆分出来,为了以后的业务变更做好预留,这样设计的代码,业务扩展性会非常好,当有新的链路增加进来,改动也会非常快,代码思路,逻辑更清晰;


标签:模式,责任,tail,num,链路,chainStep,设计模式,public
From: https://blog.51cto.com/u_16158506/6463453

相关文章

  • 关于浏览器的PWA模式
    浏览器的PWA模式是一种可安装(Installable),可以出现在设备的主屏幕。关于开发如何识别PWA模式constisInStandaloneMode=()=>(window.matchMedia('(display-mode:standalone)').matches)......
  • Redis集群-哨兵模式搭建(1主2从3哨兵节点)
    Redis集群-哨兵模式搭建(1主2从3哨兵节点)原创 北极星 运维记事 2023-04-2022:47 发表于四川收录于合集#redis8个主机规划类型IP地址端口号主192.168.77.1456379从1192.168.77.1466379从2192.168.77.1476379哨兵1192.168.77.14526379哨兵2......
  • MySql5.7主从同步配置(gtid模式)
    mysql数据库主从同步配置是开发中比较常见的需求,在MySql里,主从同步主要有两种,bin-log和gtid。下面就主要总结一下使用gtid模式配置主从同步的过程。1.概念全局事务标识:globaltransactionidentifiers;GTID是一个事务一一对应,并且全局唯一ID;一个GTID在一个服务器上只执行一次,避免......
  • 设计模式之装饰者模式--钢铁侠的形成
    前言本文主要讲述java常见设计模式之装饰者模式,文中使用通俗易懂的案例,使你更好的学习本章知识点并理解原理,做到有道无术。一.什么是装饰者模式装饰者模式是23种设计模式中结构型模式的一种,它的核心思想是在不必改变类文件及不使用继承的情况下,通过装饰者包裹目标对象,动态地扩......
  • Android中Activity的启动模式
    Android中Activity的启动模式一共有4种,分别是standard、singleTop、singleTask、singleInstance,可以在AndroidManifest.xml中通过给<activity>标签指定android:launchMode属性来指定启动模式。1、standard在standard模式下,每当启动一个新的Activity,他就会在返回栈中入栈,并处于......
  • 05.工厂方法模式
    使用工厂方法模式来解决问题定义定义一个用于创建对象的接口,让子类决定实例化哪一个类,FactoryMethod使一个类的实例化延迟到其子类。应用工厂方法式来解决问题的思路工厂方法模式的解决思路很有意思,那就是不解决,采取无为而治的方式:不是需要接口对象吗,那就定义一个方法来创......
  • redis四种模式
    1、单机模式单机模式就是在一台服务器上安装redis,然后启动,所有业务都调用这一台redis服务器。优点:部署简单,只需要在一台服务器上安装并启动redis就行。成本低,没有备用节点,不需要其他的开支。高性能,单机不需要同步数据,数据天然一致性。缺点:可靠性较弱,一旦服务器宕机,所有业务......
  • 代理模式的简单理解
    1.废话​ 上次io流联系的时候,有一个地方有待优化,计划使用代理模式。恰逢开始写博客,着闲着也是闲着记录一下丰富一下我的博客记录,之前看过一些网上其他的代理的讲解都很高端,我这技术有限只说一下自己理解的代理模式2.背景​ 之前统计项目中废没在被使用的VUE文件时写了一个遍历......
  • 单例模式(static应用场景)
     单例模式(Singleton) 设计-->一个类只能创建一个对象有效减少内存占用空间 设计一个系统--->百度搜索引擎 publicclassBaidu{ publicvoid搜索(Stringkeyword){ } } 创建一个Baidu对象new 调用搜索的方法做事情方法执行一遍 同一时间有很多很多......
  • VMware Workstation 桥接模式的网卡上让虚拟机使用 VLAN 的正确方法
    要解决的问题有一个虚拟机运行在VMWareworkstation中,如何让这个虚拟机桥接到宿主机的网络上的某个VLAN?常见使用场景只有一个网口的单臂软路由,同时宿主机为Windows,虚拟机软件为VMwareWorkstation,在虚拟机中运行OpenWrt需要在一个网口上,利用VLAN实现虚拟WAN口上的P......