什么是责任链模式?有哪些应用?

一、定义、目的

责任链模式的目的是避免请求发送者与多个接收者之间的耦合关系,将这些接收者组成一条链,并沿着这条链传递请求,直到有一个接收者处理它为止。

在责任链模式中,通常将处理请求的对象称为处理器或者链的节点,每个节点都包含了处理该请求的逻辑以及指向下一个节点的引用。当请求到达一个节点时,如果该节点无法处理该请求,它会将请求转发给下一个节点,直到有一个节点处理该请求或者整个链都无法处理该请求。

二、应用场景:

责任链模式在实际开发中有很多应用场景,比如:

1、过滤器链:在Web开发中,可以通过责任链模式来实现过滤器链,例如Spring框架中FilterChain就是一条责任链,每个过滤器都有机会对请求进行处理,直到最后一个过滤器处理完毕。

2、日志记录器:在日志系统中,可以使用责任链模式来将日志记录器组成一条链,从而实现多种日志记录方式的灵活组合。

3、异常处理器:在应用程序中,可以使用责任链模式来实现异常处理器的链式调用,从而灵活地处理各种异常情况。

4、授权认证:在系统中,可以使用责任链模式来实现授权认证的链式调用,从而灵活地控制不同用户对系统的访问权限。

三、示例

下面以一个订单处理的场景为例,介绍如何使用责任链模式:

假设我们有一个在线商店,当用户下单时,订单需要经过以下几个步骤:

1、检查订单信息是否完整

2、检查商品库存是否充足

3、检查用户余额是否充足

4、确认订单,更新商品库存和用户余额

我们可以将每个步骤封装成一个处理者,然后使用责任链模式将它们连接起来,形成一个处理链。

首先定义一个处理者接口OrderHandler:

复制代码
public interface OrderHandler{
    void handle(Order order);
}

然后实现每个步骤对应的Handler:

复制代码
public class CheckOrderHandler implements OrderHandler {
    private OrderHandler next ;
    public CheckOrderHandler (OrderHandler next) {
        this.next = next ;
    }
    @Override
    public void handle(Order order) {
        //检查订单信息是否完整
        if (order.isInfoComplete()) {
            //如果订单信息完整,则将请求传递给下一一个处理者
            next.handle(order) ;
        } else {
            //如果订单信息不完整,则直接返回错误信息
            throw new RuntimeException( "订单信息不完整") ;
            }
        }
    }
public class CheckStockHandler implements OrderHandler {
    private OrderHandler next ;
    public CheckStockHandler (OrderHandler next) {
        this.next = next ;
    }
    @Override
    public void handle(Order order) {
        //检查商品库存是否充足
        if (order.getStock() >= order.getQuantity()) {
            //如果库存充足,则将请求传递给下一个处理者
              next.handle( order ) ;
        } else{
            //如果库存不足,则直接返回错误信息
            throw new RuntimeException( "商品库存不足") ;
        }
    }
}

public class CheckBalanceHandler implements OrderHandler {
    private OrderHandler next ;
    public CheckBalanceHandler (OrderHandler next) {
        this.next = next ;
    }
    @Override
    public void handle(Order order) {
        //检查用户余额是否充足
        if (order.getBalance() >= order. get Amount() ) {
            //如果余额充足,则将请求传递给下一个处理者
            next.handle( order ) ;
        } else {
            //如果余额不足,则直接返回错误信息
            throw new RuntimeException( "用户余额不足") ;
        }
    }
}
public class Confi rmOrderHandler implements OrderHandler {
        @Override
        public void handle(Order order) {
            // 确认订单,更新商品库存和用户余额
            order.confirm( ) ;
        }
}

其中每个处理者都有一个指向下一个处理者的引用,处理者之间通过调用下一个处理者的handle方法将请求传递下去。如果某个处理者无法处理请求,则直接返回错误信息。最后,再将这些Handler串联起来按顺序执行即可。

复制代码
//客户端代码示例
CheckOrderHandler checkOrderHandler = new CheckOrderHandler();
CheckStockHandler checkStockHandler = new CheckStockHandler();
CheckBalanceHandler checkBalanceHandler = new CheckBalanceHandler();
ConfirmOrderHandler confirmOrderHandler = new ConfirmOrderHandler();

// 将处理器按照一定顺序组成责任链
checkOrderHandler.setNext (checkStockHandler) ;
checkStockHandler.setNext (checkBalanceHandler) ;
check BalanceHandler.setNext (confirmOrderHandler) ;

//处理订单
Order order = new Order( ) ;
checkOrderHandler.handle(order) ;
相关推荐
渣哥40 分钟前
原来 Java 里线程安全集合有这么多种
java
间彧1 小时前
Spring Boot集成Spring Security完整指南
java
间彧1 小时前
Spring Secutiy基本原理及工作流程
java
数据智能老司机2 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
Java水解2 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
数据智能老司机3 小时前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
洛小豆4 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学5 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole5 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端
华仔啊5 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端