【软考】设计模式之责任链模式

news2024/9/20 11:32:02

目录

          • 1. 说明
          • 2. 应用场景
          • 3. 结构图
          • 4. 构成
          • 5. 适用性
          • 6. 优点
          • 7. 缺点
          • 8. java示例

1. 说明
  • 1.使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
  • 2.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
  • 3.责任链模式(Chain of Responsibility Pattern)是一种行为设计模式。
  • 4.它为请求的发送者和接收者之间解耦提供了一种相对松散的耦合方式,使得多个对象都有机会处理这个请求,或者将这个请求传递给链中的下一个对象。
  • 5.这种模式将多个处理者对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
  • 6.这种模式给予请求传递的灵活性,并且使得对象不需要知道链的结构。
2. 应用场景
  • 1.多个对象可以处理一个请求,但具体由哪个对象处理在运行时决定。
  • 2.在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 3.可动态指定一组对象处理请求。
3. 结构图

在这里插入图片描述

4. 构成
  • 1.抽象处理者(Handler):定义一个处理请求的接口,通常包含一个或多个指向下一个处理者的引用(即链中的下一个节点)和一个处理请求的接口方法。(可选)实现后继链。
  • 2.具体处理者(Concrete Handler):实现了抽象处理者角色定义的接口,主要负责处理它负责的请求,或者将请求转发给链中的下一个处理者,以及可以访问链中下一个处理者的引用。处理它所负责的请求;可访问它的后继者;如果可处理该请求,就处理它,否则将该请求转发给后继者。
  • 3.客户端(Client):创建处理链,并向链中的第一个处理者对象提交请求。向链上的具体处理者(ConcreteHandler)对象提交请求。
5. 适用性
  • 1.有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  • 2.想在不明确指定接收者的情况下向多个对象中的一个提交一个请求。
  • 3.可处理一个请求的对象集合应被动态指定。
6. 优点
  • 1.降低耦合度:将请求的发送者和接收者解耦。
  • 2.简化对象:使得对象不需要知道链的结构。
  • 3.增强给请求分配职责的灵活性:通过改变链内的成员或调动它们的次序,允许动态地新增或者删除处理者。
  • 4.增加新的处理类很容易:无须修改现有代码,符合开闭原则。
7. 缺点
  • 1.不能保证请求一定被处理:如果没有处理者处理该请求,请求就会一直传递下去,直到链的末尾。
  • 2.系统性能会受到一定影响:因为请求在链中传递,每个处理者都需要对请求进行判断,增加了系统响应时间。
  • 3.调试复杂:链中处理者众多,增加了系统复杂性,可能难以追踪和调试。
8. java示例
  • 1.日志处理器接口
package com.learning.responsibility.example;

// 日志处理器接口
public interface Logger {  
    void log(LogMessage message);  
    void setNextLogger(Logger nextLogger);  
} 
  • 2.日志级别枚举
package com.learning.responsibility.example;

// 日志级别枚举
public enum LogLevel {  
    INFO, DEBUG, ERROR  
} 
  • 3.日志消息类
package com.learning.responsibility.example;

// 日志消息类
public class LogMessage {  
    private LogLevel level;  
    private String message;  
  
    public LogMessage(LogLevel level, String message) {  
        this.level = level;  
        this.message = message;  
    }  
  
    public LogLevel getLevel() {  
        return level;  
    }  
  
    public String getMessage() {  
        return message;  
    }  
}
  • 4.抽象日志处理器类
package com.learning.responsibility.example;

// 抽象日志处理器类
public abstract class AbstractLogger implements Logger {  
    protected int level;  
    protected Logger nextLogger;  
  
    @Override
    public void setNextLogger(Logger nextLogger) {
        this.nextLogger = nextLogger;  
    }  
  
    protected void writeToLog(String message) {  
        System.out.println("日志级别:" + level + ", 日志内容:" + message);
    }  
  
    @Override  
    public void log(LogMessage message) {  
        if (this.level <= message.getLevel().ordinal()) {  
            write(message);  
        }  
        if (nextLogger != null) {  
            nextLogger.log(message);  
        }  
    }  
  
    abstract protected void write(LogMessage message);  
}
  • 5.INFO日志处理器
package com.learning.responsibility.example;

// INFO日志处理器
public class InfoLogger extends AbstractLogger {  
    public InfoLogger(int level) {  
        this.level = level;  
    }  
  
    @Override  
    protected void write(LogMessage message) {  
        if (message.getLevel() == LogLevel.INFO) {  
            writeToLog(message.getMessage());  
        }  
    }  
} 
  • 6.DEBUG日志处理器
package com.learning.responsibility.example;

// DEBUG日志处理器
public class DebugLogger extends AbstractLogger {  
    public DebugLogger(int level) {  
        this.level = level;  
    }  
  
    @Override  
    protected void write(LogMessage message) {  
        if (message.getLevel() == LogLevel.DEBUG) {  
            writeToLog(message.getMessage());  
        }  
    }  
}  
  • 7.ERROR日志处理器
package com.learning.responsibility.example;

// ERROR日志处理器
public class ErrorLogger extends AbstractLogger {  
    public ErrorLogger(int level) {  
        this.level = level;  
    }  
  
    @Override  
    protected void write(LogMessage message) {  
        if (message.getLevel() == LogLevel.ERROR) {  
            writeToLog(message.getMessage());  
        }  
    }  
}
  • 8.应用类
package com.learning.responsibility.example;

public class Client {
    public static void main(String[] args) {
        Logger loggerChain = null; // 创建日志处理器链
        Logger infoLogger = new InfoLogger(LogLevel.INFO.ordinal());
        Logger debugLogger = new DebugLogger(LogLevel.DEBUG.ordinal());
        Logger errorLogger = new ErrorLogger(LogLevel.ERROR.ordinal());

        // 设置链
        infoLogger.setNextLogger(debugLogger);
        debugLogger.setNextLogger(errorLogger);

        loggerChain = infoLogger;

        // 发送日志消息
        loggerChain.log(new LogMessage(LogLevel.INFO, "info级别日志"));
        loggerChain.log(new LogMessage(LogLevel.DEBUG, "debug级别日志"));
        loggerChain.log(new LogMessage(LogLevel.ERROR, "error级别日志"));
    }
}
  • 9.示例截图
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【漏洞复现】易天智能eHR CreateUser 任意用户添加漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

81页PPT产业园5G多功能智慧灯杆整体规划设计方案

学习9000多份智慧城市&#xff0c;智慧医院&#xff0c;智能制造&#xff0c;数字化转型&#xff0c;新质生产力&#xff0c;算力&#xff0c;大模型&#xff0c;AIGC&#xff0c;工业互联网&#xff0c;数字孪生......持续更新热点行业解决方案&#xff0c;公号智慧方案文库。…

计算机网络 --- 【2】计算机网络的组成、功能

目录 一、计算机网络的组成 1.1 从组成部分看 1.2 从工作方式看 1.3 从逻辑功能看 1.4 总结 二、计算机网络的功能 2.1 数据通信 2.2 资源共享​编辑 2.3 分布式处理 2.4 提高可靠性 2.5 负载均衡 一、计算机网络的组成 1.1 从组成部分看 我们举例分析计算机网络从…

Mistral.rs开源大语言模型(LLM)推理平台兼容OpenAI API,通过HTTP服务器和Python绑定

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

十、组合模式

组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式能够让客户端以统一的方式对待单个对象和对象集合&#xff0c;使得客户端在处理复杂树形结构的时候&#xff0c;可以以…

读者来信:《人机环境系统智能》读后感

一、什么是智能&#xff1f; 当“人工智能”火爆出圈乃至登堂入室&#xff0c;上升为国家战略层面后&#xff0c;尽管我们每天都把人工智能挂在嘴上&#xff0c;但好像似乎忘了问一句&#xff1a;什么是智能&#xff1f;经过一番在哲学上对控制论、信息论、系统论在哲学上的追根…

MES实施困难点简述

调研数据显示&#xff0c;企业认为多部门协调难度大、各类数据采集难度大、定制化程度高是MES系统实施过程中最为突出的三个难点&#xff0c;比例分别达到52%、48%、46%。其他如对MES认识不足、难以准确把握需求、企业相关人才比较匮乏、与其他系统边界难以划分等也是实施过程中…

加密与安全_优雅存储用户密码的最佳实践

文章目录 Pre概述最佳实践避免使用MD5、SHA1等快速哈希算法加盐哈希 &#xff08;不推荐&#xff09;使用BCrypt、Argon2等慢哈希算法 (推荐)BCrypt Code1. 自动生成和嵌入盐2. 哈希结果的格式3. 代价因子 BCrypt特点 防止暴力破解1. 登录失败锁定2. 双因素认证&#xff08;2FA…

MATLAB | 绘图复刻(十七) | 半小提琴图

嘿&#xff0c;真的是好久不见&#xff0c;最近有点过于忙了&#xff0c;今天更一个好久之前粉丝问的半小提琴图的绘制方法&#xff0c;要复刻这张图&#xff1a; 绘制效果如下&#xff1a; 还是挺好看的&#xff0c;下面直接进入正题&#xff1a; 教程部分 0 数据准备 这里…

Redis学习Day3——项目工程开发

扩展阅读推荐&#xff1a; 黑马程序员Redis入门到实战教程_哔哩哔哩_bilibili 一、项目介绍及其初始化 学习Redis的过程&#xff0c;我们还将遇到各种实际问题&#xff0c;例如缓存击穿、雪崩、热Key等问题&#xff0c;只有在实际的项目实践中解决这些问题&#xff0c;才能更好…

DPDI基础版安装部署说明

DispatchPDI下载 DPDI online部署包下载地址&#xff1a; Windows: http://files.pizzalord.site/api/public/dl/7Tnq6ScE/release/dpdi-community-win.zip Linux: http://files.pizzalord.site/api/public/dl/otCt9WuI/release/dpdi-community-linux.zip DPDI部署 DPDI应…

python构建深度学习模型开发数据采集利器,为模型提供充足图像数据

经常需要接触到各种各样的图像数据&#xff0c;为模型开发准备素材&#xff0c;在实际的项目中&#xff0c;一部分数据来源于真实的项目场景&#xff0c;但是这部分数据大都比较少&#xff0c;且获取的难度比较大&#xff0c;往往都是项目到了实施阶段的时候才有机会拿到数据&a…

基于SpringBoot的医院挂号预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的医院挂号预约管理…

【有啥问啥】探索扫地机器人中的 SLAM 算法:原理、实现与未来展望

探索扫地机器人中的 SLAM 算法&#xff1a;原理、实现与未来展望 随着智能家居的普及&#xff0c;扫地机器人逐渐成为日常生活中的常见家电。其自主导航能力使得它能够在复杂的家庭环境中高效完成清洁任务&#xff0c;而这背后的核心技术之一就是 SLAM&#xff08;Simultaneou…

CCS12.2 以及以上版本如何使用C2000ware 4.03版本,发现直接导入工程不能正确识别地址变量?

C2000ware 5.02 地址变量为&#xff1a;COM_TI_C2000WARE_INSTALL_DIR&#xff0c;CCS12.2以上版本能够直接匹配识别&#xff01; 但是C2000ware4.03版本地址变量为&#xff1a;COM_TI_C2000WARE_SOFTWARE_PACKAGE_INSTALL_DIR&#xff0c;这个不能直接识别到头文件的地址&…

appium server gui详细按照步骤

1.安装appium server desktop Appium安装提供两种方式:桌面版和命令行版。其中桌面版又分为 Appium GuI 和 Appium Desktop 。作为初学者&#xff0c;用桌面版&#xff0c;对初学者比较友好。 官网下载地址&#xff1a;Releases appium/appium-desktop GitHubTags appium/…

基于FPGA与RK3588的多通道低延时3G-SDI视频信号

目录 简介 主要用途&#xff1a; 项目简介&#xff1a; 详细过程&#xff1a; BT1120视频时序转CEA861 视频像素编码格式转换 低延时处理 MIPI接口处理 视频处理模块 ​​​​​​​ 简介 主要解决 RK3588支持多种视频格式输入&#xff0c;但是没有支持多路SDI接口的…

【JUC】14-LongAddr源码分析

1. LongAddr底层实现过程 2. Striped64中变量或方法的定义 base&#xff1a;类似于AtomicLong中全局的value值。在没有竞争情况下数据直接累加到base上&#xff0c;或者cells扩容时&#xff0c;也需要将数据写入到base上。collide&#xff1a;表示扩容意向&#xff0c;false一…

反转链表 II

题目 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1a;…

Java中的ArrayList类

继承实现关系 Arraylist就是一个可以动态扩容的容器&#xff0c;属于集合类的一种&#xff0c;要追根溯源的话它是间接实现了Collection接口&#xff0c;下面我画一下它的结构图 类定义 ArrayList类继承自抽象类AbstractList&#xff0c;同时实现了List和Collection接口&…