09-责任链模式-C语言实现

责任链模式:Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求, 从而避免了请求的发送者和接受者之间的耦合关系。 将这些对象连成一条链, 并沿着这条链传递该请求, 直到有对象处理它为止。 )

UML图:


代码实现:

#include <stdio.h>
#include <stdlib.h>// 定义请求结构体
typedef struct {int amount;
} Request;// 定义处理对象结构体
typedef struct Handler {void (*handleRequest)(struct Handler* handler, Request* request);struct Handler* nextHandler;
} Handler;// 处理对象1
void handler1_handleRequest(Handler* handler, Request* request) {if (request->amount <= 100) {printf("Handler 1 handles the request.\n");} else if (handler->nextHandler != NULL) {handler->nextHandler->handleRequest(handler->nextHandler, request);}
}// 处理对象2
void handler2_handleRequest(Handler* handler, Request* request) {if (request->amount > 100 && request->amount <= 500) {printf("Handler 2 handles the request.\n");} else if (handler->nextHandler != NULL) {handler->nextHandler->handleRequest(handler->nextHandler, request);}
}// 处理对象3
void handler3_handleRequest(Handler* handler, Request* request) {if (request->amount > 500) {printf("Handler 3 handles the request.\n");} else if (handler->nextHandler != NULL) {handler->nextHandler->handleRequest(handler->nextHandler, request);}
}int main() {// 创建处理对象Handler* handler1 = (Handler*)malloc(sizeof(Handler));Handler* handler2 = (Handler*)malloc(sizeof(Handler));Handler* handler3 = (Handler*)malloc(sizeof(Handler));// 设置处理函数和下一个处理对象handler1->handleRequest = handler1_handleRequest;handler1->nextHandler = handler2;handler2->handleRequest = handler2_handleRequest;handler2->nextHandler = handler3;handler3->handleRequest = handler3_handleRequest;handler3->nextHandler = NULL;// 创建请求Request request1 = {50};Request request2 = {200};Request request3 = {1000};// 处理请求handler1->handleRequest(handler1, &request1);handler1->handleRequest(handler1, &request2);handler1->handleRequest(handler1, &request3);// 释放内存free(handler1);free(handler2);free(handler3);return 0;
}

此示例实现了一个简单的责任链模式,有三个处理对象(handler1、handler2和handler3),每个处理对象都可以选择处理请求或将其传递给下一个处理对象。每个处理对象都具有一个处理请求的函数指针,并且可以通过nextHandler字段连接到下一个处理对象。

责任链模式的优点:

  1. 解耦:责任链模式使得请求的发送者和接收者之间解耦,发送者无需知道请求将由哪个接收者处理,接收者也无需知道请求的发送者是谁。
  2. 灵活性:可以动态地添加、移除或重新排列处理对象,以满足不同的需求和情况。
  3. 可扩展性:可以很容易地添加新的处理对象,而无需修改现有的代码。

责任链模式的缺点:

  1. 不能保证请求一定会被处理:如果没有合适的处理对象处理请求,请求可能会到达链的末尾而无法得到处理。
  2. 性能影响:由于请求需要通过整个链进行传递,可能会在一些场景下造成性能损失。
  3. 可能导致系统复杂化:当责任链过长或过于复杂时,可能会增加代码的理解和维护难度。

应用场景:

  1. 请求处理:当一个请求需要经过多个处理对象进行处理时,可以使用责任链模式。每个处理对象都有自己的处理逻辑,并可以选择将请求传递给下一个处理对象或者终止处理。

  2. 日志记录:在日志记录系统中,可以使用责任链模式来实现不同级别的日志记录。例如,可以定义一个处理对象链,其中包含了不同级别的日志处理对象,从低级别到高级别。每个处理对象根据自己的级别来判断是否要处理该日志消息。

  3. 身份认证:在身份认证系统中,可以使用责任链模式来验证用户的身份。可以创建一个处理对象链,其中包含了不同的身份验证处理对象,如用户名密码验证、二次验证等。每个处理对象根据自己的验证规则来判断是否通过验证,如果验证失败,则可以选择终止验证或将请求传递给下一个处理对象。

  4. 缓存处理:在缓存系统中,可以使用责任链模式来处理缓存。可以创建一个处理对象链,其中包含了多个缓存处理对象,如本地缓存、分布式缓存等。每个处理对象根据自己的策略来判断是否有缓存可用,如果有,则返回缓存数据,否则将请求传递给下一个处理对象。

  5. 错误处理:在错误处理系统中,可以使用责任链模式来处理不同类型的错误。可以创建一个处理对象链,其中包含了多个错误处理对象,如日志记录、发送错误报告等。每个处理对象根据自己的处理逻辑来判断是否能够处理该错误,如果不能,则将错误传递给下一个处理对象。

  6. 版本号处理

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

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

相关文章

Java学习苦旅(二十三)——二叉搜索树

本篇博客将详细讲解二叉搜索树。 文章目录 二叉搜索树概念操作查找插入删除 性能分析 结尾 二叉搜索树 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根…

java数据结构与算法刷题-----LeetCode64. 最小路径和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 很多人觉得动态规划很难&#xff0c;但它就是固定套路而已。其实动态规划只…

最新ChatGPT网站系统源码+详细搭建部署教程+Midjourney绘画AI绘画

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

CogVLM多模态大模型训练代码详细教程(基于vscode调试与训练)

文章目录 前言一、cogvlm环境安装1、apex问题2、en_core_web_sm问题 二、launch.json文件配置1、finetune_cogvlm_lora.sh被配置内容2、launch.json文件配置3、debug调试展示 三、训练源码解读1、权重问题2、数据问题3、训练模型参数修改4、训练源码解读5、训练结果展示 前言 …

认识Git

&#x1f30e;初识Git 初识Git 什么是Git Git的安装       Centos平台安装Git       Ubuntu平台安装Git Git的基本操作       创建远程仓库       配置Git 认识工作区、暂存区与版本库       添加文件到暂存区       将暂存区文件提交至本…

weak_ptr如何能做到解决循环引用又能传递参数呢?

引子&#xff1a;今天在看CLR via C#的时候看到C#的垃圾回收算法--引用跟踪算法的时候想到以下几个问题。 一、引用计数法存在的问题 一般引用计数法存在的问题就是不好处理循环引用的问题&#xff0c;但是C不是有weak_ptr吗&#xff1f; 这个引用跟踪的垃圾回收算法看起来还…

MySQL忘记密码,如何重置密码(Windows)

1. 停止MySQL服务 打开“服务”管理工具&#xff08;可以在开始菜单搜索“服务”或运行 services.msc&#xff09;。 找到你的MySQL服务&#xff0c;可能叫别的&#xff0c;但是应该都是mysql开头的。 鼠标右键停止运行它。 2. 跳过权限表启动 MySQL 打开命令提示符&#x…

HTML5 新元素

新多媒体元素 标签描述<audio>定义音频内容<video>定义视频&#xff08;video 或者 movie&#xff09;<source>定义多媒体资源 <video> 和 <audio><embed>定义嵌入的内容&#xff0c;比如插件。<track>为诸如 <video> 和 <…

理论U2 贝叶斯决策理论

文章目录 一、概率统计理论基础1、乘法公式2、全概率公式3、贝叶斯公式 二、贝叶斯决策理论1、用处2、解决问题3、决策基础4、一些概念5、核心公式 三、最小错误率贝叶斯决策1、目标2、例题分析3、问题1&#xff09;决策的风险 四、最小风险贝叶斯决策1、背景2、基本概念1&…

西电期末1034.勒让德多项式

一.题目 二.分析与思路 带递推式即可&#xff0c;注意数据类型的使用和转换&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 int main() {int n;double x;scanf("%d%lf",&n,&x);double ans0;double num[n];num[0]1;num[1]x;//初始化ansnum…

VS2017 CMake编译Opencv

先下载opencv4.2.0源码以及opencv_contrib-4.2.0 地址链接&#xff1a;https://pan.baidu.com/s/1AgFsiH4uMqTRJftNXAqmTw?pwd3663 提取码&#xff1a;3663 先建立一个opencv_debug和opencv_release文件夹这两个都是为了后续存放编译好的debug版本和release版本opencv的&#…

jaeger简单发送---链路追踪

jaeger go发送单个span package mainimport ("fmt""github.com/uber/jaeger-client-go"jaegercfg "github.com/uber/jaeger-client-go/config" )func main() {cfg : jaegercfg.Configuration{Sampler: &jaegercfg.SamplerConfig{ //采样类…

小程序 蓝牙连接与回连过程

小程序蓝牙连接过程包括扫描设备、连接设备和发送数据等步骤 具体步骤如下&#xff1a; 打开蓝牙&#xff1a;在小程序中调用wx.openBluetoothAdapter()函数打开蓝牙适配器。 监听蓝牙适配器状态&#xff1a;使用wx.onBluetoothAdapterStateChange()函数监听蓝牙适配器的状态…

2023年12 月电子学会Python等级考试试卷(一级)答案解析

青少年软件编程(Python)等级考试试卷(一级) 分数:100 题数:37 一、单选题(共25题,共50分) 1. 下列程序运行的结果是?( ) print(hello) print(world) A. helloworld

部署可道云网盘的一个漏洞解决

目录 1漏洞展示 2.防范措施 1漏洞展示 因为可道云网盘的上传文档有保存在 /data/Group/public/home/文档/ 中,当别有用心之人知道个人部署的域名与上次的文件后&#xff0c;可以进行访问拿到uid。例我在我部署的网盘上上次一个aa.php 文件&#xff0c;然后拿来演示 然后通过…

LeetCode刷题笔记之栈与队列

一、队列与栈相互转换 1. 232【用栈实现队列】 题目&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末…

Java SE入门及基础(5)

变量的定义与使用 1. 变量的概念 从字面意思看&#xff0c;变量就是会变化的量。 从计算机专业角度看&#xff0c;变量就是一个内存空间地址的表示。 在Java中&#xff0c;内存分为栈内存和堆内存两大块 2. 变量的声明 语法 数据类型 变量名 ; 变量名 变量值…

Python笔记07-异常、模块和包

文章目录 异常及捕获方法python模块python包安装第三方包 异常及捕获方法 当检测到一个错误时&#xff0c;Python解释器就无法继续执行了&#xff0c;反而出现了一些错误的提示&#xff0c;这就是所谓的“异常”, 也就是我们常说的BUG 例如&#xff1a;以r方式打开一个不存在的…

LNMP架构及应用部署

目录 简介 1、构建LNMP网站平台 1.1、安装MySQL数据库 &#xff08;1&#xff09;编译安装MySQL &#xff08;2&#xff09;优化调整 &#xff08;3&#xff09;初始化数据库 &#xff08;4&#xff09;启动mysql服务 1.2、安装PHP解析环境 &#xff08;1&#xf…

【pytorch学习】 深度学习 教程 and 实战

pytorch编程实战博主&#xff1a;https://github.com/lucidrains https://github.com/lucidrains/vit-pytorch