当前位置: 首页 > news >正文

责任链模式:优雅处理请求的设计艺术

责任链模式:优雅处理请求的设计艺术

引言

在软件开发的世界里,我们常常会遇到需要对请求进行一系列处理的场景。比如,一个电商系统中,订单从创建到最终完成交易,需要经过创建订单、付款、发货、确认收货、交易结束等多个步骤。如果将这些处理逻辑都耦合在一起,代码会变得复杂且难以维护。而责任链模式正是为解决这类问题而生,它能够让我们以一种优雅的方式来处理请求。

责任链模式概述

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求为止。在这个模式中,每个处理者都有一个引用指向下一个处理者,形成一个链条。当一个请求进入这个链条时,它会依次经过每个处理者,每个处理者可以选择处理该请求或者将其传递给下一个处理者。

责任链模式的结构

责任链模式主要包含以下几个角色:

  1. 抽象处理者(Handler):定义了处理请求的接口,通常包含一个设置下一个处理者的方法和一个处理请求的抽象方法。
  2. 具体处理者(Concrete Handler):实现了抽象处理者的接口,负责处理请求或者将请求传递给下一个处理者。
  3. 客户端(Client):创建处理者链,并将请求发送给链中的第一个处理者。

责任链模式的实现

下面我们以一个简单的订单处理系统为例,来演示责任链模式的实现。

1. 定义订单类

class Order {
    private boolean isCreated;
    private boolean isPaid;
    private boolean isShipped;
    private boolean isReceived;
    private boolean isCompleted;

    public boolean isCreated() {
        return isCreated;
    }

    public void setCreated(boolean created) {
        isCreated = created;
    }

    public boolean isPaid() {
        return isPaid;
    }

    public void setPaid(boolean paid) {
        isPaid = paid;
    }

    public boolean isShipped() {
        return isShipped;
    }

    public void setShipped(boolean shipped) {
        isShipped = shipped;
    }

    public boolean isReceived() {
        return isReceived;
    }

    public void setReceived(boolean received) {
        isReceived = received;
    }

    public boolean isCompleted() {
        return isCompleted;
    }

    public void setCompleted(boolean completed) {
        isCompleted = completed;
    }

    @Override
    public String toString() {
        return "Order{" +
                "isCreated=" + isCreated +
                ", isPaid=" + isPaid +
                ", isShipped=" + isShipped +
                ", isReceived=" + isReceived +
                ", isCompleted=" + isCompleted +
                '}';
    }
}

2. 定义抽象处理者类

abstract class OrderHandler {
    protected OrderHandler nextHandler;

    // 支持链式调用的设置下一个处理者的方法
    public OrderHandler setNextHandler(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
        return nextHandler;
    }

    public abstract void handleOrder(Order order);
}

3. 实现具体处理者类

// 创建订单处理者
class CreateOrderHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (!order.isCreated()) {
            System.out.println("创建订单...");
            order.setCreated(true);
        }
       
        Optional.ofNullable(nextHandler).ifPresent(x-> x.handleOrder(order));
    }
}

// 付款处理者
class PaymentHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isCreated() && !order.isPaid()) {
            System.out.println("付款...");
            order.setPaid(true);
        }
         Optional.ofNullable(nextHandler).ifPresent(x-> x.handleOrder(order));
    }
}

// 发货处理者
class ShippingHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isPaid() && !order.isShipped()) {
            System.out.println("发货...");
            order.setShipped(true);
        }
        Optional.ofNullable(nextHandler).ifPresent(x-> x.handleOrder(order));
    }
}

// 确认收货处理者
class ConfirmReceiptHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isShipped() && !order.isReceived()) {
            System.out.println("确认收货...");
            order.setReceived(true);
        }
         Optional.ofNullable(nextHandler).ifPresent(x-> x.handleOrder(order));
    }
}

// 交易结束处理者
class TransactionCompletedHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isReceived() && !order.isCompleted()) {
            System.out.println("交易结束...");
            order.setCompleted(true);
        }
         Optional.ofNullable(nextHandler).ifPresent(x-> x.handleOrder(order));
    }
}

4. 使用

public class OrderProcessingChain {
    public static void main(String[] args) {
        // 创建处理者
        CreateOrderHandler createOrderHandler = new CreateOrderHandler();
        PaymentHandler paymentHandler = new PaymentHandler();
        ShippingHandler shippingHandler = new ShippingHandler();
        ConfirmReceiptHandler confirmReceiptHandler = new ConfirmReceiptHandler();
        TransactionCompletedHandler transactionCompletedHandler = new TransactionCompletedHandler();

        // 链式设置处理者链
        createOrderHandler
               .setNextHandler(paymentHandler)
               .setNextHandler(shippingHandler)
               .setNextHandler(confirmReceiptHandler)
               .setNextHandler(transactionCompletedHandler);

        // 创建订单
        Order order = new Order();

        // 开始处理订单
        createOrderHandler.handleOrder(order);

        // 输出订单状态
        System.out.println(order);
    }
}

代码解释

  • Order 类:表示订单,包含订单的各个状态信息。
  • OrderHandler 类:抽象处理者类,定义了设置下一个处理者的方法 setNextHandler 和抽象处理方法 handleOrder
  • 具体处理者类:每个具体处理者类(如 CreateOrderHandlerPaymentHandler 等)负责处理订单的一个特定步骤,并在处理完成后将订单传递给下一个处理者(如果存在)。
  • OrderProcessingChain 类:客户端代码,创建处理者链并将订单传递给链中的第一个处理者

运行结果

创建订单...
付款...
发货...
确认收货...
交易结束...
Order{isCreated=true, isPaid=true, isShipped=true, isReceived=true, isCompleted=true}

责任链模式的优点和缺点

优点

  1. 解耦请求和处理:责任链模式将请求的发送者和接收者解耦,使得请求的发送者不需要知道具体是哪个处理者处理请求,只需要将请求发送给链中的第一个处理者即可。
  2. 可扩展性强:可以方便地添加或修改处理者,只需要调整处理者链的顺序或添加新的处理者即可。
  3. 灵活性高:可以根据需要动态地调整处理者链的顺序和组成。

缺点

  1. 请求可能得不到处理:如果处理者链没有正确设置或者没有合适的处理者,请求可能会一直传递下去,最终得不到处理。
  2. 调试困难:由于请求的处理过程是在处理者链中依次传递的,当出现问题时,调试起来可能会比较困难。

总结

责任链模式是一种非常实用的设计模式,它能够帮助我们优雅地处理请求,提高代码的可维护性和可扩展性。在实际开发中,当遇到需要对请求进行一系列处理的场景时,不妨考虑使用责任链模式来解决问题。但同时也要注意其可能带来的缺点,合理使用该模式,以达到最佳的开发效果。

相关文章:

  • Docker运行Mysql异常:Operation not permitted
  • OceanBase 读写分离最佳实践
  • ADB三个模块介绍
  • C# HTTP认证方式详解与代码实现
  • Docker 最佳实践(MySQL)
  • [spring] Spring JPA - Hibernate 多表联查 1
  • K8S学习之基础三十三:K8S之监控Prometheus部署程序版
  • 【蓝桥杯python研究生组备赛】005 数学与简单DP
  • windows安装金仓V9初始化数据库失败
  • Grid 布局实现三栏布局
  • Vue3:构建高效用户界面的利器
  • VUE中使用路由router跳转页面
  • HTTP请求方法详解:GET、POST、PUT在微信小程序中的应用
  • uni-app——计时器和界面交互API
  • Python 整数类型(int)大全
  • 大数据在人力资源管理中的洞察与决策
  • [动手学习深度学习] 27.含并行连结的网络 GoogLeNet/Inception v3
  • RabbitMQ八股文
  • 【Java导出word】使用poi-tl轻松实现Java导出数据到Word文档
  • PyTorch中Batch Normalization1d的实现与手动验证
  • 四川:全省统一取消普通住宅和非普通住宅标准
  • 拉卡拉一季度净利约1亿降超五成,去年净利3.5亿降逾23%
  • 海南高院通报去年知产领域司法保护状况:审结民事一审案件4847起
  • 昆明一小区电梯突然从40楼降到负4楼,回应:临时断电引起
  • 最高法:“盗链”属于信息网络传播行为,构成侵犯著作权罪
  • 唐仁健违规收受礼品、礼金被点名!十起违反中央八项规定精神典型问题被通报