设计模式行为型——责任链模式

这篇具有很好参考价值的文章主要介绍了设计模式行为型——责任链模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

什么是责任链模式

责任链模式的实现

责任链模式角色

责任链模式类图

责任链模式举例

责任链模式代码实现

责任链模式的特点

优点

缺点

使用场景

注意事项

实际应用


什么是责任链模式

        责任链模式(Chain of Responsibility Pattern)又叫职责链模式是一种行为型设计模式,它通过建立一个对象链来依次处理请求,将请求的发送者和接收者解耦,并允许多个对象都有机会处理请求。其目的是为了解决请求端与实现端的解耦。其实现过程类似递归调用。责任链模式的核心是定义责任链节点的接口以及节点之间的关系,它允许动态的增加和修改责任链中的节点。

责任链模式的实现

责任链模式角色

  1. 抽象处理者(Handler):定义了处理请求的接口,并维护一个指向下一处理者的引用。通常包含一个处理方法 handleRequest()。
  2. 具体处理者(ConcreteHandler):实现了抽象处理者接口,对请求进行具体处理,如果自身无法处理,则将请求转发给下一处理者。

责任链模式类图

设计模式行为型——责任链模式,设计模式,设计模式,责任链模式

责任链模式举例

        以公司采购审批为例,不同金额的采购需要不同人员的审批,比如20000以下需要项目经理审批,20000-50000需要部门经理审批,50000以上需要总经理审批。此时我们把审批流程可以看作一个审批责任链条,进而可以使用责任链模式。

责任链模式代码实现

实体请求类

package com.common.demo.pattern.chain;

import java.math.BigDecimal;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 实体请求类
 * @date 2023/07/27 13:35:41
 */
public class PurchaseReq {

    /**
     * 请求类型
     */
    private int type;

    /**
     * 金额
     */
    private BigDecimal price;

    /**
     * 用途
     */
    private String purpose;

    public PurchaseReq(int type, BigDecimal price, String purpose) {
        this.type = type;
        this.price = price;
        this.purpose = purpose;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public String getPurpose() {
        return purpose;
    }

    public void setPurpose(String purpose) {
        this.purpose = purpose;
    }

    @Override
    public String toString() {
        return "PurchaseReq{" +
                "type=" + type +
                ", price=" + price +
                ", purpose=" + purpose +
                '}';
    }
}

抽象处理者角色

package com.common.demo.pattern.chain;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 抽象审批者处理类, 抽象处理者角色
 * @date 2023/07/27 13:44:42
 */
public abstract class Approver {

    Approver approver;
    String name;

    public Approver() {
    }

    public Approver(String name) {
        this.name = name;
    }

    /**
     * 下一个处理者
     */
    public void setApprover(Approver approver) {
        this.approver = approver;
    }



    /**
     * 处理审批请求的方法,得到一个请求,处理是子类实现
     */
    public abstract void process(PurchaseReq purchaseReq);

}

具体处理者角色

package com.common.demo.pattern.chain;

import java.math.BigDecimal;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 项目经理 具体审批者
 * @date 2023/07/27 13:49:16
 */
public class ProjectManager extends Approver {

    public ProjectManager(String name) {
        super(name);
    }

    @Override
    public void process(PurchaseReq purchaseReq) {
        // 小于 5000 项目经理审批即可
        if (purchaseReq.getPrice().compareTo(new BigDecimal(5000)) == -1) {
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,审批终结!");
        } else {
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,进入下一级审批!");
            approver.process(purchaseReq);
        }
    }
}
package com.common.demo.pattern.chain;

import java.math.BigDecimal;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 部门经理 具体审批者
 * @date 2023/07/27 13:49:48
 */
public class DepartmentManager extends Approver{

    public DepartmentManager(String name) {
        super(name);
    }

    @Override
    public void process(PurchaseReq purchaseReq) {
        // 小于 20000 大于 5000, 部门经理审批即可
        if(purchaseReq.getPrice().compareTo(new BigDecimal(20000))==-1){
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,审批终结!");
        } else {
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,进入下一级审批!");
            approver.process(purchaseReq);
        }
    }
}
package com.common.demo.pattern.chain;

import java.math.BigDecimal;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 总经理 具体审批者
 * @date 2023/07/27 13:50:45
 */
public class GeneralManager extends Approver {

    public GeneralManager(String name) {
        super(name);
    }

    @Override
    public void process(PurchaseReq purchaseReq) {
        // 大于 20000 ,总经理审批
        if (new BigDecimal(20000).compareTo(purchaseReq.getPrice()) == -1) {
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,审批终结!");
        } else {
            System.out.println("采购计划:"+purchaseReq.getPurpose()+",被"+this.name+"处理,进入下一级审批!");
            approver.process(purchaseReq);
        }
    }
}

测试类

package com.common.demo.pattern.chain;

import java.math.BigDecimal;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 测试类
 * @date 2023/07/27 14:23:01
 */
public class Test {

    public static void main(String[] args) {

        PurchaseReq purchaseRequest1 = new PurchaseReq(1, new BigDecimal(1000), "购买饮水机");
        PurchaseReq purchaseRequest2 = new PurchaseReq(2, new BigDecimal(6000), "购买打印机");
        PurchaseReq purchaseRequest3 = new PurchaseReq(2, new BigDecimal(30000), "购买苹果笔记本办公");

        ProjectManager projectManager = new ProjectManager("项目经理");
        DepartmentManager departmentManager = new DepartmentManager("部门经理");
        GeneralManager generalManager = new GeneralManager("总经理");
        //设置下一级处理人
        projectManager.setApprover(departmentManager);
        departmentManager.setApprover(generalManager);
        //都从项目经理开始处理
        projectManager.process(purchaseRequest1);
        projectManager.process(purchaseRequest2);
        projectManager.process(purchaseRequest3);

    }
}

测试截图

设计模式行为型——责任链模式,设计模式,设计模式,责任链模式

责任链模式的特点

优点

  1. 降低耦合度:将请求和处理分开,请求的发送者和接收者各个组件间完全解耦。
  2. 简化了对象:使得对象不需知道链的结构,请求者无需知道接受者,无需知道其如何处理。
  3. 增强灵活性:通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任对象。 
  4. 新增便捷性:增加新的请求处理类很方便。

缺点

  1. 因为只关心自己内部实现,不关心链内部结构,开发调试会比较麻烦。不容易确认调用的哪一个实现。
  2. 增加系统的资源消耗。因为链式调用,可能会进行很多次判断,因为每个实现都会判断是否能够处理该请求,不能处理则调用下一个,增加了系统开销。
  3. 不能保证请求被消化,因其特殊特性,在处理之前会判断是否能够处理,如果每一个链都不能处理,那么该请求无法被消化。

使用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 
  3. 可动态指定一组对象处理请求。

注意事项

  1. 合理设计责任链的节点:责任链模式的核心是将任务分解为一系列的处理节点,每个节点都有机会处理任务或将其传递给下一个节点。在设计责任链节点时,需要根据实际情况合理地划分节点责任,确保每个节点的功能清晰、独立、可扩展,并且能够按需组合形成不同的责任链。
  2. 灵活配置责任链:责任链模式支持动态配置责任链,也就是可以在运行时通过添加、移除或修改节点来构建不同的责任链。这种灵活性可以根据实际需求动态调整责任链的结构和顺序,但也需要注意避免责任链过长、过于复杂,以及节点的重叠或缺失等问题。
  3. 节点的执行顺序:责任链模式中,每个节点都有机会处理任务,但处理的顺序是非常重要的。在设计责任链时,需要仔细考虑节点的执行顺序,确保任务能够按照预期的流程依次经过每个节点,同时避免出现死循环或执行顺序混乱等问题。
  4. 避免责任链的滥用:责任链模式可以很好地解耦请求发送者和接收者之间的关系,但也容易被滥用。在应用责任链模式时,需要审慎选择,确保责任链模式能够带来真正的价值,而不是增加复杂性或降低代码可维护性。
  5. 错误处理机制:在责任链模式中,如果没有合适的节点处理任务,任务可能会无法得到处理或处理结果不符合预期。因此,在设计责任链时,需要考虑错误处理机制,例如设置默认处理节点、定义异常处理策略等,以确保任务能够得到妥善处理,并且在发生异常时能够及时进行处理和反馈。

实际应用

  1. Spring框架中的拦截器:拦截器是Spring框架中的一种常见组件,它可以在请求处理前后进行一些额外的处理,例如身份验证、日志记录、权限控制等。拦截器就是利用了责任链模式来将多个处理对象构成一条拦截器链,然后逐个处理请求。Spring框架提供了很多拦截器,例如HandlerInterceptor、WebRequestInterceptor等。
  2. Servlet中的过滤器:Servlet中的过滤器也是一种常见的使用责任链模式的场景。过滤器可以在请求处理前后进行一些额外的处理,例如安全认证、数据预处理、异常处理等。
  3. Java 8中的Lambda表达式:Java 8中的Lambda表达式可以看作是一种函数式接口,它利用责任链模式来组合、封装和传递函数对象。Lambda表达式可以通过链式结构形成一个函数的序列,然后按顺序逐个执行这些函数并返回结果,从而可以在Java中实现函数式编程。
  4. Netty中的处理器Pipeline:Netty是一种基于事件驱动的网络通信框架,它利用责任链模式和事件监听机制来处理请求。Netty中的处理器Pipeline是一条处理请求的链,该链中的每个处理器都可以对请求进行处理和传递,从而形成一个完整的事件处理流程。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)文章来源地址https://www.toymoban.com/news/detail-616836.html

到了这里,关于设计模式行为型——责任链模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java设计模式之行为型-责任链模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、在Java中实现 4.2、在SpringBoot中实现  五、总结  责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行发送。请求会被链上每个处理者处理,直到请求被处理完毕。该模式主要解决的是请求的发送者和

    2024年02月15日
    浏览(39)
  • 设计模式-责任链模式

    遇到一个面试的场景题目,让实现税率的计算 请使用Java语言实现如下税率计算: 1~5000 税率 0 5001~8000 3% 8001~17000 10% 17001~30000 20% 30001~40000 25% 40001~60000 30% 60001~85000 35% 85001~ 45% 要求 ⅰ. 逻辑正确,代码优雅 ⅱ. 可扩展性,考虑区间的变化,比如说起征点从5000变成10000等等,或者

    2024年02月11日
    浏览(35)
  • 【设计模式】责任链模式

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处

    2024年02月12日
    浏览(39)
  • 设计模式—责任链模式

    一、待解决问题 : 减少代码中 if else 语句,降低代码圈复杂度或深度,增强可读性。 1、需求背景: 采购订单创建,需要验证采购员、物料、供应商、供应商的银行账号等信息。如采购员权限到期、或供应商失效等问题,都无法下单。 2、代码如下: 学习使用责任链模式后

    2024年02月10日
    浏览(45)
  • 设计模式——责任链模式

    使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有对象处理它为止。 优点 能将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦提高系

    2024年02月15日
    浏览(41)
  • 设计模式:责任链模式

    责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照顺序处理请求,直到其中一个对象能够处理该请求为止。责任链模式将请求发送者和接收者解耦,使得多个对象都有机会处理请求,同时避免了请求发送者与接收者之间的直接耦合关系。 在

    2024年02月07日
    浏览(43)
  • 《设计模式》责任链模式

    定义 : 责任链模式将链中每一个节点都看成一个对象,并且将这些节点对象连成一条链,请求会沿着这条链进行传递,直到有对象处理它为止,这使得多个对象都有机会接收请求,避免了请求发送者和接收者之间的耦合。 属于 行为型 设计模式。 责任链模式的角色组成 :

    2024年02月13日
    浏览(43)
  • 说说设计模式~责任链模式

    回到目录 它是一种设计模块,主要将操作流程与具体操作解耦,让每个操作都可以设置自己的操作流程,这对于工作流应用是一个不错的选择! 下面是官方标准的定义:责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一

    2024年02月11日
    浏览(38)
  • 设计模式07-责任链模式

    责任链模式属于行为设计模式,常见的过滤器链就是使用责任链模式设计的。 Q:假设有一个闯关游戏,共三关,每一关达到通过条件后才能进入下一关,使用java实现。 A:针对这个问题,按照朴素的想法,我们可以定义三个类,分别是第一关、第二关、第三关,客户端启动

    2024年02月16日
    浏览(41)
  • 重温设计模式 --- 责任链模式

    责任链模式 是一种行为型设计模式,它通过一条由多个处理器组成的链来处理请求,每个处理器都有机会处理请求,如果一个处理器不能处理该请求,它会将请求传递给下一个处理器,直到请求被处理为止。 在实际应用中,责任链模式常用于处理请求的分发、事件处理等场

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包