【24种设计模式】责任链模式(Chain of Responsibility Pattern)

news/2024/5/19 11:49:49 标签: 设计模式, 责任链模式, java

责任链模式是一种行为设计模式,它允许你将请求沿着处理链进行传递,直到有一个处理者能够处理该请求为止。这种模式将请求的发送者和接收者解耦,使多个对象都有机会处理该请求。

责任链模式的结构

责任链模式由以下几个角色组成:

  1. 抽象处理者(Handler):定义了处理请求的接口,并维护一个指向下一个处理者的引用。
  2. 具体处理者(ConcreteHandler):实现了处理请求的方法,如果自己不能处理该请求,则将请求传递给下一个处理者。
  3. 客户端(Client):创建具体处理者的链,并将请求发送给第一个处理者。

示例代码

以下是一个简单的示例,展示了如何在一个餐厅点餐系统中使用责任链模式

首先,定义一个抽象处理者接口:

java">public interface OrderHandler {
    void setNextHandler(OrderHandler nextHandler);
    void handleOrder(Order order);
}

然后,创建具体处理者类,分别处理不同类型的订单:

java">public class OnlineOrderHandler implements OrderHandler {
    private OrderHandler nextHandler;

    @Override
    public void setNextHandler(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getType().equals("online")) {
            // 处理在线订单的逻辑
            System.out.println("处理在线订单:" + order);
        } else {
            // 将请求传递给下一个处理者
            nextHandler.handleOrder(order);
        }
    }
}

public class PhoneOrderHandler implements OrderHandler {
    private OrderHandler nextHandler;

    @Override
    public void setNextHandler(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getType().equals("phone")) {
            // 处理电话订单的逻辑
            System.out.println("处理电话订单:" + order);
        } else {
            // 将请求传递给下一个处理者
            nextHandler.handleOrder(order);
        }
    }
}

public class WalkInOrderHandler implements OrderHandler {
    private OrderHandler nextHandler;

    @Override
    public void setNextHandler(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getType().equals("walk-in")) {
            // 处理现场订单的逻辑
            System.out.println("处理现场订单:" + order);
        } else {
            // 将请求传递给下一个处理者
            nextHandler.handleOrder(order);
        }
    }
}

在每个具体处理者中,根据订单的类型来判断是否能够处理该订单。如果能够处理,则执行相应的业务逻辑;否则,将订单传递给下一个处理者。

最后,在客户端创建处理者链并使用它来处理订单:

java">public class OrderHandlerChain {
    private OrderHandler firstHandler;

    public void addHandler(OrderHandler handler) {
        if (firstHandler == null) {
            firstHandler = handler;
        } else {
            OrderHandler currHandler = firstHandler;
            while (currHandler.getNextHandler() != null) {
                currHandler = currHandler.getNextHandler();
            }
            currHandler.setNextHandler(handler);
        }
    }

    public void handleOrder(Order order) {
        if (firstHandler != null) {
            firstHandler.handleOrder(order);
        }
    }
}

public class Client {
    public static void main(String[] args) {
        OrderHandlerChain chain = new OrderHandlerChain();

        // 创建具体处理者
        OrderHandler onlineHandler = new OnlineOrderHandler();
        OrderHandler phoneHandler = new PhoneOrderHandler();
        OrderHandler walkInHandler = new WalkInOrderHandler();

        // 构建处理者链
        chain.addHandler(onlineHandler);
        chain.addHandler(phoneHandler);
        chain.addHandler(walkInHandler);

        // 创建订单
        Order order1 = new Order("online");
        Order order2 = new Order("phone");
        Order order3 = new Order("walk-in");

        // 处理订单
        chain.handleOrder(order1);
        chain.handleOrder(order2);
        chain.handleOrder(order3);
    }
}

在客户端的 main() 方法中,创建了具体处理者和处理者链,并构建了一个包含不同类型订单处理逻辑的责任链。然后,通过链式调用处理者的 handleOrder() 方法,将订单传递给责任链进行处理。

责任链模式的使用场景

责任链模式适用于以下情况:

  • 当你希望多个对象都有机会处理请求,并且你不确定哪个对象会处理请求时。
  • 当你希望在不显式指定接收者的情况下,将请求的发送者和接收者解耦。
  • 当你希望动态地指定处理对象集合,并在处理链中添加或移除处理者时。

常见的应用场景包括:

  • 日志记录系统:可以将日志请求沿着处理链传递,由不同的处理器负责处理不同级别的日志。
  • 请求过滤器:可以使用责任链模式来处理请求过滤逻辑,例如对请求进行权限验证、防止恶意请求等。
  • 用户界面事件处理:可以使用责任链模式来处理用户界面事件,例如鼠标点击、键盘输入等。

责任链模式可以帮助我们构建松耦合、灵活和可扩展的系统。通过使用责任链模式,我们可以轻松地添加、修改或移除处理者,以适应不同的业务需求。

希望这篇博客推文能够帮助你理解责任链模式,并在实际开发中得到应用!如果还有其他问题,请随时提问。


http://www.niftyadmin.cn/n/5060526.html

相关文章

数据结构--Trie字符串统计

1、“Trie树” 作用: 高效地存储和查找字符串集合的数据结构。 2、“Trie树” 存储字符串的形式如下: 用 “0” 来表示 “根节点(root)”。存入一个字符串时,会在字符串最后结尾的那个字符节点打上标记。比如&#x…

Linux高性能服务器编程 学习笔记 第九章 IO复用

IO复用使程序能同时监听多个文件描述符,这可以提高程序的性能,通常网络程序在以下情况需要使用IO复用: 1.客户端进程需要同时处理多个socket。 2.客户端进程需要同时处理用户输入和网络连接。 3.TCP服务器要同时处理监听socket和连接socket…

【SSL】用Certbot生成免费HTTPS证书

1. 实验背景 服务器:CentOS7.x 示例域名: www.example.com 域名对应的web站点目录: /usr/local/openresty/nginx/html 2. 安装docker # yum -y install yum-utils# yum-config-manager --add-repo https://download.docker.com/linux/ce…

Spring MVC 中的国际化和本地化

Spring MVC 中的国际化和本地化 国际化(Internationalization,简称i18n)和本地化(Localization,简称l10n)是构建多语言应用程序的重要概念。Spring MVC提供了丰富的支持,使开发人员能够轻松地处…

MyBatisPlus(六)字段映射 @TableField

字段注解(非主键) TableField 用于映射对象的 属性 和表中的 字段 。 当 属性名 和 字段名 差异较大的时候,无法通过默认的映射关系对应起来,就需要指定 属性名 对应 的 字段名。 官网示例 代码实例 package com.example.web.…

Spring的bean和对象的区别

在Spring框架中,Bean和对象是两个非常重要的概念。虽然它们看起来很相似,但实际上它们之间有一些重要的区别。 首先,让我们来看看什么是Bean。在Spring中,Bean是一个由Spring IoC容器管理的对象,它遵循特定的命名规则…

ARM底层汇编基础指令

汇编语言的组成 伪操作 不参与程序执行,但是用于告诉编译器程序怎么编译.text .global .end .if .else .endif .data 汇编指令 编译器将一条汇编指令编译成一条机器码,在内存里一条指令占4字节内存,一条指令可以实现一个特定的功能 伪指令 不…

《Vue.js+Spring Boot全栈开发实战》简介

大家好,我是老卫。 恰逢中秋国庆双节,不想出门看人山,惟愿宅家阅书海! 今天开箱的这本书是《Vue.jsSpring Boot全栈开发实战》。 外观 从书名故名思议,就是基于Vue.jsSpring Boot来实现企业级应用全栈开发。 该书由…