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

一、定义、目的

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

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

二、应用场景:

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

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) ;
相关推荐
独自破碎E7 分钟前
Java是怎么实现跨平台的?
java·开发语言
To Be Clean Coder14 分钟前
【Spring源码】从源码倒看Spring用法(二)
java·后端·spring
xdpcxq102933 分钟前
风控场景下超高并发频次计算服务
java·服务器·网络
想用offer打牌36 分钟前
你真的懂Thread.currentThread().interrupt()吗?
java·后端·架构
橘色的狸花猫1 小时前
简历与岗位要求相似度分析系统
java·nlp
独自破碎E1 小时前
Leetcode1438绝对值不超过限制的最长连续子数组
java·开发语言·算法
用户91743965391 小时前
Elasticsearch Percolate Query使用优化案例-从2000到500ms
java·大数据·elasticsearch
yaoxin5211231 小时前
279. Java Stream API - Stream 拼接的两种方式:concat() vs flatMap()
java·开发语言
坚持学习前端日记2 小时前
2025年的个人和学习年度总结以及未来期望
java·学习·程序人生·职场和发展·创业创新
Cosmoshhhyyy2 小时前
《Effective Java》解读第29条:优先考虑泛型
java·开发语言