C++ 设计模式之责任链模式

【声明】本题目来源于卡码网(卡码网KamaCoder)

【提示:如果不想看文字介绍,可以直接跳转到C++编码部分


设计模式大纲】


【简介】

        --什么是责任链模式(第21种设计模式)

        责任链模式是⼀种行为型设计模式,它允许你构建⼀个对象链,让请求从链的⼀端进⼊,然后沿着链上的对象依次处理,直到链上的某个对象能够处理该请求为止。

        职责链上的处理者就是⼀个对象,可以对请求进⾏处理或者将请求转发给下⼀个节点,这个场景在⽣活中很常⻅,就是⼀个逐层向上递交的过程,最终的请求要么被处理者所处理,要么处理不了,这也因此可能导致请求⽆法被处理。


 【组成结构】

        责任链模式包括以下几个基本结构:

  • 1. 处理者Handler :定义⼀个处理请求的接⼝,包含⼀个处理请求的抽象⽅法和⼀个指向下⼀个处理者的链接。
  • 2. 具体处理者ConcreteHandler : 实现处理请求的⽅法,并判断能否处理请求,如果能够处理请求则进⾏处理,否则将请求传递给下⼀个处理者。
  • 3. 客户端:创建并组装处理者对象链,并将请求发送到链上的第⼀个处理者


 【简易实现 - Java】

        以Java代码作以简要说明

1. 处理者

        定义处理请求的接口

interface Handler {// 处理请求的⽅法void handleRequest(double amount);// 设置下⼀个处理者的⽅法void setNextHandler(Handler nextHandler);
}

2. 具体处理者

        实现处理请求

class ConcreteHandler implements Handler {private Handler nextHandler;@Overridepublic void handleRequest(Request request) {// 根据具体情况处理请求,如果⽆法处理则交给下⼀个处理者if (canHandle(request)) {// 处理请求的逻辑} else if (nextHandler != null) {// 交给下⼀个处理者处理nextHandler.handleRequest(request);} else {// ⽆法处理请求的逻辑}}@Overridepublic void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}// 具体处理者⾃⼰的判断条件private boolean canHandle(Request request) {// 根据具体情况判断是否能够处理请求return /* 判断条件 */;}
}

3. 客户端

        创建并组装处理者对象链,将请求发送给链上第⼀个处理者

public class Main {public static void main(String[] args) {// 创建处理者实例Handler handler1 = new ConcreteHandler();Handler handler2 = new ConcreteHandler();// ...// 构建责任链handler1.setNextHandler(handler2);// ...// 发送请求Request request = new Request(/* 请求参数 */);handler1.handleRequest(request);}
}

【使用场景】

        责任链模式具有下⾯⼏个优点:

  • 降低耦合度:将请求的发送者和接收者解耦,每个具体处理者都只负责处理与⾃⼰相关的请求,客户端不需要知道具体是哪个处理者处理请求。
  • 增强灵活性:可以动态地添加或删除处理者,改变处理者之间的顺序以满⾜不同需求。

        但是由于⼀个请求可能会经过多个处理者,这可能会导致⼀些性能问题,并且如果整个链上也没有合适的处理者来处理请求,就会导致请求⽆法被处理。
        责任链模式是设计模式中简单且常⻅的设计模式,在⽇常中也会经常使⽤到,⽐如Java开发中过滤器的链式处理,以及Spring框架中的拦截器,都组装成⼀个处理链对请求、响应进⾏处理。


【C++编码部分】

1. 题目描述

        小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。

        审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。

2. 输入描述

        第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"。

3. 输出描述

        对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。

4. C++编程示例(可直接运行)

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file DutyChainMode.hpp
* @brief 责任链模式
* @autor 写代码的小恐龙er
* @date 2024/01/25
*/#include <iostream>
#include <string>using namespace std;// 前置声明// 用户请求类
class LeaveRequest;//  处理者 接口类
class LeaveHandler;
// 具体处理者1 -- 主管(Supervisor) 3
class Supervisor;
// 具体处理者2 -- 经理(Manager) 7 
class Manager;
// 具体处理者3 -- 董事(Director) 10
class Director;// 具体定义// 用户请求类
class LeaveRequest
{
//成员数据
private:string _name;int _daysLeave = 0;
// 成员函数
public://构造函数LeaveRequest(string name, int days){this->_name = name;this->_daysLeave = days;}// 成员数据获取接口string GetName(){return this->_name;}int GetDaysLeave(){return this->_daysLeave;}
};//  处理者 接口类
class LeaveHandler
{
// 接口
public:virtual void HandleRequest(LeaveRequest *request) = 0;
};// 具体处理者1 -- 主管(Supervisor) 3
class Supervisor : public LeaveHandler
{
//成员数据
private:const int _maxDays = 3;// 下一个处理者LeaveHandler *_nextHandler;
// 接口函数重载
public:// 构造函数Supervisor(){}Supervisor(LeaveHandler *nextHandler){this->_nextHandler = nextHandler;}void HandleRequest(LeaveRequest *request) override {if(request){if(request->GetDaysLeave() <= _maxDays){std::cout << request->GetName() << " Approved by Supervisor." << endl;}else if(_nextHandler){_nextHandler->HandleRequest(request);}else std::cout << request->GetName() << " Denied by Supervisor." << endl;}}
};// 具体处理者2 -- 经理(Manager) 7 
class Manager : public LeaveHandler
{
//成员数据
private:const int _maxDays = 7;// 下一个处理者LeaveHandler *_nextHandler;
// 接口函数重载
public:// 构造函数Manager(){}Manager(LeaveHandler *nextHandler){this->_nextHandler = nextHandler;}void HandleRequest(LeaveRequest *request) override {if(request){if(request->GetDaysLeave() <= _maxDays){std::cout << request->GetName() << " Approved by Manager." << endl;}else if(_nextHandler){_nextHandler->HandleRequest(request);}else std::cout << request->GetName() << " Denied by Manager." << endl;}}
};// 具体处理者3 -- 董事(Director) 10
class Director : public LeaveHandler
{
//成员数据
private:const int _maxDays = 10;// 下一个处理者const LeaveHandler *_nextHandler = nullptr;
// 接口函数重载
public:// 构造函数Director(){}// Director(LeaveHandler *nextHandler){//     this->_nextHandler = nextHandler;// }void HandleRequest(LeaveRequest *request) override {if(request){if(request->GetDaysLeave() <= _maxDays){std::cout << request->GetName() << " Approved by Director." << endl;}// else if(_nextHandler){//     _nextHandler->HandleRequest(request);// }else std::cout << request->GetName() << " Denied by Director." << endl;}}
};int main()
{// 请求数量int requestNum = 0;std::cin >> requestNum;// 创建请求命令基类LeaveRequest *request = nullptr;// 创建处理者基类 -- 【创建处理流程时 也可单独创建一个类】LeaveHandler *director = new Director();LeaveHandler *manager = new Manager(director);LeaveHandler *supervisor = new Supervisor(manager);// 遍历for(int i = 0; i < requestNum; i++){// 请假者姓名 和 天数string name = "";int days = 0;// 输入std::cin >> name >> days;// 新建请求类request = new LeaveRequest(name, days);// 开始处理请求supervisor->HandleRequest(request);}//析构delete director;director = nullptr;delete manager;manager = nullptr;delete supervisor;supervisor = nullptr;if(request != nullptr){delete request;request = nullptr;}return 0;
}


......

To be continued.

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

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

相关文章

windows下git pull超时,ping不通github

报错 ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 解决办法 修改hosts 最后加一行&#xff0c;文件位置&#xff1a;…

redis主从复制薪火相传

一.主从复制 1、是什么 主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c;Master以写为主&#xff0c;Slave以读为主 2、能干嘛 读写分离&#xff0c;性能扩展&#xff08;主 写 从 读&#xff09; 容…

Vue中使用TypeScript:全面指南和最佳实践

🚀 欢迎来到我的专栏!专注于Vue3的实战总结和开发实践分享,让你轻松驾驭Vue3的奇妙世界! 🌈✨在这里,我将为你呈现最新的Vue3技术趋势,分享独家实用教程,并为你解析开发中的难题。让我们一起深入Vue3的魅力,助力你成为Vue大师! 👨‍💻💡不再徘徊,快来关注…

第14章_数据结构与集合源码(一维数组,链表,栈,队列,树与二叉树,List接口分析,Map接口分析,Set接口分析,HashMap的相关问题)

文章目录 第14章_数据结构与集合源码本章专题与脉络1. 数据结构剖析1.1 研究对象一&#xff1a;数据间逻辑关系1.2 研究对象二&#xff1a;数据的存储结构&#xff08;或物理结构&#xff09;1.3 研究对象三&#xff1a;运算结构1.4 小结 2. 一维数组2.1 数组的特点2.2 自定义数…

渲染与创造之美:互为表里的艺术

在五彩斑斓的艺术世界中&#xff0c;渲染与创造是两股不可或缺的力量。它们之间的关系&#xff0c;恰如弓与箭&#xff0c;互为表里&#xff0c;共同塑造出无数令人叹为观止的视觉景象。创造之美是指通过创新思维和创造力&#xff0c;将想象具象化为现实&#xff0c;创造出新的…

vscode开发FPGA(1)---TEROS_HDL插件报错

一、TerosHDL:modelsim(vlog-66)报错 Error: (vlog-66) Execution of vlib.exe failed 解决办法&#xff1a; 1.新建modelsim工程&#xff0c;并随意编译一个.v文件&#xff0c;将产生的work目录复制到modelsim安装路径下。 2.再将vscode设置verilog>linting>modelsim…

armv8 - GIC-V2 中断控制器

GIC起源 上一节中&#xff0c;粗略讲了hylicos上用的armv7上的一个通用中断控制器&#xff0c;其只支持60个中断源。但现代SoC上&#xff0c;中断系统正变得越来越复杂&#xff0c;旧的中断控制器已经无法胜任这些系统&#xff0c;主要体现在以下几点上&#xff1a; 中断源越…

OceanBase创建租户

租户是集群之上的递进概念&#xff0c;OceanBase 数据库采用了多租户架构。 集群偏部署层面的物理概念&#xff0c;是 Zone 和节点的集合&#xff0c;租户则偏向于资源层面的逻辑概念&#xff0c;是在物理节点上划分的资源单元&#xff0c;可以指定其资源规格&#xff0c;包括…

800G光传输网络中的相干调制与PAM4技术

在800G光传输网络架构中&#xff0c;相干调制技术和PAM4&#xff08;四电平脉冲幅度调制&#xff09;技术各具优势&#xff0c;分别针对不同应用场景提供高效解决方案。 相干调制是高级光通信的核心技术之一&#xff0c;它通过精密操控光载波的频率、相位和振幅来编码信息&…

RabbitMQ 笔记一

概览&#xff1a; MQ基本概念 RabbitMQ入门 基本工作模 1.MQ是什么&#xff1f; MQ:Message Queue, 存储消息的中间件&#xff0c;是消息发送过程中的暂存容器&#xff0c;主要用于解决分布式系统进程间的通信。 分布式系统通信的两种方式&#xff1a;直接远程调用、借助第三…

Idea上操作Git回退本地版本,怎么样保留已修改的文件,回退本地版本的四种方式代表什么?

Git的基本概念:Git是一个版本控制系统,用于管理代码的变更历史记录。核心概念包括仓库、分支、提交和合并。 1、可以帮助开发者合并开发的代码 2、如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突 3、代码文件版本管理 问题描述 当我们使用git提交代码…

Linux本地部署SVN服务结合内网穿透实现远程访问

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

php下curl发送cookie

目录 一&#xff1a;使用 CURLOPT_COOKIE 选项 二&#xff1a;CURLOPT_COOKIEFILE 三&#xff1a;CURLOPT_HTTPHEADER php curl发送cookie的几种方式,下面来介绍下 一&#xff1a;使用 CURLOPT_COOKIE 选项 通过设置 CURLOPT_COOKIE 选项&#xff0c;你可以将 cookie 字符…

el-table 动态渲染多级表头;一级表头根据数据动态生成,二级表头固定

一、表格需求&#xff1a; 实现一个动态表头&#xff0c;一级表头&#xff0c;根据数据动态生成&#xff0c;二级表头固定&#xff0c;每列的数据不一样&#xff0c;难点在于数据的处理。做这种表头需要两组数据&#xff0c;一组数据是实现表头的&#xff0c;另一组数据是内容…

《WebKit技术内幕》学习之十三(3):移动WebKit

3 其他机制 3.1 新渲染机制 为了移动领域更好的用户体验&#xff0c;渲染机制所做的改进主要是提升渲染性能来增加响应的速度&#xff0c;甚至不惜牺牲一些跟规范定义的行为不一致的地方。在这一小节中主要介绍三个方面的技术&#xff0c;其一是Tiled Backing Store&#x…

81.网游逆向分析与插件开发-背包的获取-装备栏数据结构的逆向分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;自动化助手显示物品数据-CSDN博客 然后游戏中有弓箭&#xff0c;弓箭有数量&#xff0c;可以作为突破口&#xff0c;也可以使用物品id 获取弓的方式 获取弓箭的方式 然后搜索250 然后搜索出一个 然后…

C语言-算法-线性dp

[USACO1.5] [IOI1994]数字三角形 Number Triangles 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。 在上面的样例中&#xff0c;从 7 → 3 → 8 →…

k8s-基础知识(Pod,Deployment,ReplicaSet)

k8s职责 自动化容器部署和复制随时扩展或收缩容器容器分组group&#xff0c;并且提供容器间的负载均衡实时监控&#xff0c;即时故障发现&#xff0c;自动替换 k8s概念及架构 pod pod是容器的容器&#xff0c;可以包含多个container pod是k8s最小可部署单元&#xff0c;容器…

从物联网看智慧文旅的未来:技术与实践的完美结合,重塑旅游体验的新篇章

一、物联网技术&#xff1a;智慧文旅的基石 随着科技的飞速发展&#xff0c;物联网技术已经深入到我们生活的方方面面&#xff0c;尤其在智慧文旅领域&#xff0c;物联网技术更是起到了不可或缺的作用。它如同智慧文旅的基石&#xff0c;为旅游行业带来了前所未有的创新和变革…

Elasticsearch内核解析 - 数据模型篇

Elasticsearch内核解析 - 数据模型篇 - 知乎 Elasticsearch是一个实时的分布式搜索和分析引擎&#xff0c;它可以帮助我们用很快的速度去处理大规模数据&#xff0c;可以用于全文检索、结构化检索、推荐、分析以及统计聚合等多种场景。 Elasticsearch是一个建立在全文搜索引擎…