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.mzph.cn/news/648662.shtml

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

相关文章

C语言实现希尔排序算法(附带源代码)

希尔排序 希尔排序&#xff0c;也称递减增量排序算法&#xff0c;是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的&#xff1a; 插入排序在对几乎已经排好序的数据操作时&#xff0c;效率高&#xff0…

Java PDFBox 提取页数、PDF转图片

PDF 提取 使用Apache 的pdfbox组件对PDF文件解析读取和转图片。 Maven 依赖 导入下面的maven依赖&#xff1a; <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.30</version> &l…

基于Docker、Minikube在PC端构建K8S试验环境

在桌面电脑上使用Docker和Minikube构建Kubernetes&#xff08;K8S&#xff09;试验环境&#xff0c;为学习和测试提供了一个理想的平台。Docker的容器化技术允许在隔离的环境中运行应用&#xff0c;而Minikube则简化了在单节点上部署和管理Kubernetes集群的过程。这种组合使得个…

Apipost-cli、Jenkins持续集成配置

安装 Apipost-cli npm install -g apipost-cli 运行脚本 安装好Apipost-cli后&#xff0c;在命令行输入生成的命令&#xff0c;即可执行测试用例&#xff0c;运行完成后会展示测试进度并生成测试报告。 Jenkins配置 Apipost cli基于Node js运行 需要在jenkins上配置NodeJs依…

eNSP 实验 两台AR配置同网段

实验1&#xff1a;eNSP 两台AR配置同网段 目的&#xff1a;创建两台AR&#xff0c;配置IP互相ping通 拓扑结构&#xff1a; 首先创建一个AR3260 然后创建一个AR2220 然后同轴电缆连接一下 先配置AR2220。 1、切管理员&#xff1a;system-view 进入千兆位以太网 0/0/0 interf…

MIT_线性代数笔记:第 29 讲 奇异值分解

目录 如何实现用矩阵数学语言描述这一过程举例 本讲介绍奇异值分解&#xff08;Singular value decomposition&#xff09;&#xff0c;简称 SVD。这是矩阵最终也是最好的分解&#xff0c;任意矩阵可分解为 A U Σ V T AUΣV^T AUΣVT&#xff0c;分解结果为正交矩阵 U&#x…

day31_HTML

今日内容 0 复习昨日 1 表格标签 2 表单标签【重要】 3 框架标签 0 复习昨日 Javaweb开发,前端,服务器,数据库 前端,要学习HTML,CSS,JavaScript,JQuery HTML是用来编写网页的一种编程语言 语法 由各种标签组成,标签是尖括号<>,一般都是成对儿出现,前面叫做开标签,后面…

excel中多行合并后调整行高并打印

首先参考该文&#xff0c;调整全文的行高。 几个小技巧&#xff1a; 1.转换成pdf查看文件格式 2.通过视图--》分页预览&#xff0c;来确定每页的内容&#xff08;此时页码会以水印的形式显示&#xff09; 3. 页面布局中的&#xff0c;宽度可以选为自动&#xff0c;因为已经是…

Linux——系统简介

1、从UNIX到LINUX 在目前主流的服务器端操作系统中&#xff0c;UNIX诞生于20世纪60年代末&#xff0c;Windows诞生于20世纪80年代中期&#xff0c;Linux诞生于20世纪90年代初&#xff0c;可以说UNIX是操作系统中的“老大哥”。 1.1、Linux简史 Linux内核最初是由李纳斯托瓦兹…

[TII 2023] 基于压缩感知的多级隐私保护方案

Multilevel Privacy Preservation Scheme Based on Compressed Sensing | IEEE Journals & Magazine | IEEE Xplore 摘要 物联网的广泛应用在给人们带来便利的同时&#xff0c;也引发了人们对数据采集、分析和共享过程中隐私泄露的担忧。本文提出了一种基于压缩感知的多级…

Cesium数据加载

文章目录 0.引言1.影像加载1.1Bing地图1.2天地图1.3ArcGIS在线地图1.4高德地图1.5OSM影像1.6MapBox影像 2.OGC地图服务2.1WMS2.2WMTS2.3TMS 3.GeoJSON数据加载4.KML数据加载5.TIFF数据加载6.点云数据加载7.地形数据加载7.1在线地形数据加载7.2本地地形数据加载 8.倾斜摄影模型数…

[BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)

第15天 名词解释 Cookie 是小型的文本文件&#xff0c;由网站发送到用户的浏览器&#xff0c;并存储在用户的设备上。Cookie 通常用于存储识别用户的信息&#xff0c;例如用户偏好、登录状态等。每当用户再次访问同一网站时&#xff0c;浏览器会将 Cookie 发送回服务器&#…

10 个值得分享给你前端低代码项目

今天来分享 10 个优秀的前端低代码项目&#xff01;企业级低代码快速开发平台&#xff0c;包含页面可视化配置、自定义表单、自定义报表、权限管理脚手架应用、前后端代码自动生成&#xff1b;主要特点是低代码开发&#xff0c;可实现复杂CRUD功能仅编写数据模型就能完成前后端…

扫雷游戏 bevy 实践(bevy 0.12)-1

经典的扫雷游戏 bevy 实践&#xff08;bevy 0.12&#xff09; 网上大多是0.6的 但愿大家能够摸索着 上手 参考资料&#xff1a; Bevy Minesweeper: Introduction - DEV Community &#xff08;原始教程&#xff0c;0.6版本&#xff09; https://github.com/leonidv/bevy-m…

在线教育App、H5、微信小程序项目

大型多端项目&#xff0c;uni-app开发 一、首页 二、课程页 以点击购买&#xff0c;购买后可以看到课程内容 种课程音频、视频等&#xff0c;以及专栏&#xff0c;都可以购买后观看 三、电子书 订阅成功后&#xff0c;就可以观看电子书了 选择章节 直播模块&#xff1a; 订阅…

Linux 一键部署influxd2-telegraf 二进制方式

influxd2前言 influxd2 是 InfluxDB 2.x 版本的后台进程,是一个开源的时序数据库平台,用于存储、查询和可视化时间序列数据。它提供了一个强大的查询语言和 API,可以快速而轻松地处理大量的高性能时序数据。 telegraf 是一个开源的代理程序,它可以收集、处理和传输各种不…

零基础学习数学建模——(四)备战美赛

本篇博客将讲解如何备战美赛。 什么是美赛 美赛&#xff0c;全称是美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff09;&#xff0c;由美国数学及其应用联合会主办&#xff0c;是最高的国际性数学建模竞赛&#xff0c;也是世界范围内最具影响力的数学建模竞赛。 赛题内容…

CuteHttpFileServer

需求 最近行政同时需要做文件共享&#xff0c;使用windows上的文件共享有些问题&#xff0c;ftp也是有问题&#xff0c;同时需要身份验证功能&#xff0c;找了很久&#xff0c;发现CuteHttpFileServer 这个文件服务器&#xff0c;可以解决这个需求&#xff0c;中间过程中也写过…

生产问题复盘!Swap对GC的影响

Swap 1. 什么是Swap swap 是把一块磁盘空间或者一个本地文件当做内存来使用。可用内存无法满足内存分配请求的时候&#xff0c;把不常用的内存数据存储到磁盘&#xff0c;并在内存中释放这部分内存。当进程再次访问这部分内存的时候&#xff0c;再读取到内存中来。 2. 为什么…

详讲api网关之kong的基本概念及安装和使用(一)

什么是api网关 前面我们聊过sentinel&#xff0c;用来限流熔断和降级&#xff0c;如果你只有一个服务&#xff0c;用sentinel自然没有问题&#xff0c;但是如果是有多个服务&#xff0c;特别是微服务的兴起&#xff0c;那么每个服务都使用sentinel就给系统维护带来麻烦。那么网…