设计模式之职责链模式(ChainOfResponsibility)的C++实现
1、职责链模式的提出
在软件开发过程中,发送者经常发送一个数据请求给特定的接收者对象,让其对请求数据进行处理(一个数据请求只能有一个对象对其处理)。如果发送的每个数据请求指定特定的接收者, 将带来发送者与接收者的紧密解耦合问题。职责链模式可以将请求发送者与接收者解耦。职责链模式的处理流程是:设计一个职责链处理基类,该类具有指向下一个待处理类的变量,通过set接口设置下一个待处理的链对象成员;该类具有遍历处理请求的功能,遍历过程中,只要有一个对象处理了请求,则停止遍历;该基类抽象了2个接口分别为:判断是否处理该类型请求和处理消息的功能接口。其他的具体职责链类继承并实现职责链基类的接口。
2、需求描述
有3个职责功能类,每个职责类都只能对特定的请求数据类型进行处理,现有3个请求类型。设计一个能处理不同数据请求的功能代码,该功能代码具有良好的扩展性。数据请求的类型包括:请求类型和描述信息。
3、功能实现
(1)UML图如下:
(2)代码实现如下:
#include <iostream>
#include <string>
enum class EmType
{EM_TYPE_A,EM_TYPE_B,EM_TYPE_C
};class RequestData
{
private:std::string m_strDesc;EmType m_emType;
public:RequestData(const std::string& desc,EmType type):m_strDesc(std::move(desc)),m_emType(type){};EmType getType()const{return m_emType;};const std::string getDesc()const{return m_strDesc;};
};class ChainHandler
{
protected:ChainHandler* nextChain{nullptr};virtual void processHandler(const RequestData& request)=0;virtual bool IsHandlerType(const RequestData& request)=0;
public:void setNextChain(ChainHandler* next){nextChain = next;};void handle(const RequestData& req){if(IsHandlerType(req)){processHandler(req);}else{if(nextChain != nullptr){nextChain->handle(req);}}}virtual ~ChainHandler(){};
};class HanderA:public ChainHandler
{
public:virtual bool IsHandlerType(const RequestData &request) override{if(request.getType() == EmType::EM_TYPE_A){return true;}else{std::cout << "HanderA cannot process the request:" << request.getDesc() << std::endl;return false;}}virtual void processHandler(const RequestData& request) override{std::cout << "HanderA is processing the request: " << request.getDesc() << std::endl;}
};class HanderB:public ChainHandler
{
public:virtual bool IsHandlerType(const RequestData &request) override{if(request.getType() == EmType::EM_TYPE_B){return true;}else{std::cout << "HanderB cannot process the request:" << request.getDesc() << std::endl;return false;}}virtual void processHandler(const RequestData& request) override{std::cout << "HanderB is processing the request: " << request.getDesc() << std::endl;}
};class HanderC:public ChainHandler
{
public:virtual bool IsHandlerType(const RequestData &request) override{if(request.getType() == EmType::EM_TYPE_C){return true;}else{std::cout << "HanderC cannot process the request:" << request.getDesc() << std::endl;return false;}}virtual void processHandler(const RequestData& request) override{std::cout << "HanderC is processing the request: " << request.getDesc() << std::endl;}
};class Client
{
public:void doWork(){ChainHandler* handlerA = new HanderA();ChainHandler* handlerB = new HanderB();ChainHandler* handlerC = new HanderC();handlerA->setNextChain(handlerB);handlerB->setNextChain(handlerC);RequestData reqA("DataA need to handle",EmType::EM_TYPE_A);handlerA->handle(reqA);std::cout << "\n************** next Request ********************\n" << std::endl;RequestData reqC("DataC need to handle",EmType::EM_TYPE_C);handlerA->handle(reqC);delete handlerA;delete handlerB;delete handlerC;handlerA = nullptr;handlerB = nullptr;handlerC = nullptr;}
};int main()
{Client obj;obj.doWork();return 0;
}
程序运行结果如下:
相关文章:

设计模式之职责链模式(ChainOfResponsibility)的C++实现
1、职责链模式的提出 在软件开发过程中,发送者经常发送一个数据请求给特定的接收者对象,让其对请求数据进行处理(一个数据请求只能有一个对象对其处理)。如果发送的每个数据请求指定特定的接收者, 将带来发送者与接收…...
CGAL Mesh(网格数据)布尔操作
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Mesh布尔操作是一种在三维计算机图形学中用于组合两个或多个网格(mesh)对象的方法。它可以将两个网格对象组合成一个新的对象,同时保留原始对象的拓扑结构和几何信息。Mesh布尔操作主要有以下三种类型: Union(…...

技术分享| WebRTC之SDP详解
一,什么是SDP WebRTC 是 Web Real-Time Communication,即网页实时通信的缩写,是 RTC 协议的一种Web实现,项目由 Google 开源,并和 IETF 和 W3C 制定了行业标准。 WebRTC是点对点通讯,他的通话建立需要交换…...
Flink Table API/SQL 多分支sink
背景 在某个场景中,需要从Kafka中获取数据,经过转换处理后,需要同时sink到多个输出源中(kafka、mysql、hologres)等。两次调用execute, 阿里云Flink vvr引擎报错: public static void main(String[] args) {final StreamExecuti…...
Vue3 中 导航守卫 的使用
在Vue 3中,导航守卫(Navigation Guards)用于在路由切换前后执行一些操作,例如验证用户权限、取消路由导航等。Vue 3中的导航守卫与Vue 2中的导航守卫略有不同。下面是Vue 3中导航守卫的使用方式: 全局前置守卫…...
云原生概论
云原生是一种新兴的技术趋势,它旨在将应用程序设计和部署方式从传统的基础设施转向云端。云原生应用程序是一种针对云环境进行优化的应用程序,能够充分利用云端提供的弹性和可扩展性。本文将探讨云原生的概念、优势、应用场景以及未来发展方向。 一、云…...
hive-sql
hive-常用SQL汇总 查看数据库 -- 查看所有的数据库 show databases; 使用默认的库 -- 下面的语句可以查看默认的库 use default ;查看某个库下的表 -- 查看所有的表 show tables ; -- 查看包含 stu的表 ,这种是通配的方法来查看 show tables like *stu*; 查…...

Rspack 创建 vue2/3 项目接入 antdv(rspack.config.js 配置 less 主题)
一、简介 Rspack CLI 官方文档。 rspack.config.js 官方文档。 二、创建 vue 项目 创建项目(文档中还提供了 Rspack 内置 monorepo 框架 Nx 的创建方式,根据需求进行选择) # npm 方式 $ npm create rspacklatest# yarn 方式 $ yarn create…...
基于centos7完成docker服务的一些基础操作
目录 要求完成 具体操作 1.安装docker服务,配置镜像加速器 2.下载系统镜像(Ubuntu、 centos) 3.基于下载的镜像创建两个容器 (容器名一个为自己名字全拼,一个为首名字字母) 4.容器的启动、 停止及重启…...
Microsoft Visual Studio + Qt插件编程出现错误error MSB4184问题
文章目录 报错解决 报错 C:\Users\Administrator\AppData\Local\QtMsBuild\qt_globals.targets(786,7): error MSB4184: 无法计算表达式“[System.IO.File]::ReadAllText(C:\Users\Administrator\AppData\Local\QtMsBuild\qt.natvis.xml)”。 未能找到文件“C:\Users\Administ…...

QT Quick之quick与C++混合编程
Qt quick能够生成非常绚丽界面,但有其局限性的,对于一些业务逻辑和复杂算法,比如低阶的网络编程如 QTcpSocket ,多线程,又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等,在 QML 中要么不可…...
Ros noetic Move_base 相关状态位置的获取 实战使用教程
前言: 有一段时间没有更新,这篇文章是为了后续MPC路径跟踪算法开设的帖子用于更新我自己的思路,由于MPC算法,要镶嵌到整个导航任务中去,就绕不开这个move_base包中相关的参数设置和其中相关状态位置的获取和解读等等。 因为最近遇到小车在其他的环境中有些时候,不需要自己…...
【SpringBoot】SpringBoot项目与Vue对接接口的步骤
下面是SpringBoot项目与Vue对接接口的步骤: 创建SpringBoot项目,在项目中添加依赖,如Spring MVC、MyBatis等框架。 在SpringBoot项目中编写接口方法,使用注解标识请求方式,如GetMapping、PostMapping等,并…...
Glog安装与使用
安装 脚本 #!/bin/bash git clone https://github.com/google/glog.git cd glog git checkout v0.4.0 mkdir build && cd build cmake .. make -j4 echo "your password" | sudo -S make install使用 main.cc #include <glog/logging.h>int main(i…...
windows开发环境搭建
下载msys2,官网下载即可: MSYS2 安装其他的编译工具(貌似不需要把中间的命令全部执行): MSYS2使用教程——win10系统64位安装msys2最新版(msys2-x86_xxxx.exe)_msys64_Dreamhai的博客-CSDN博…...

8月17日上课内容 第三章 LVS+Keepalived群集
本章结构 Keepalived概述 keepalived 概述 1.服务功能 故障自动切换 健康检查 节点服务器高可用 HA keepalived工作原理 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以解决静态路由出现的单点故障问题 在一个LVS服务集群中通常有主服务器 (MAST…...

Threejs学习05——球缓冲几何体背景贴图和环境贴图
实现随机多个三角形随机位置随机颜色展示效果 这是一个非常简单基础的threejs的学习应用!本节主要学习的是球面缓冲几何体的贴图部分,这里有环境贴图以及背景贴图,这样可以有一种身临其境的效果!这里环境贴图用的是一个.hdr的文件…...
LVS+Keepalived群集实验
目录 Keepalived 是什么 Keepalived 功能 Keepalived 模块 工作原理 脑裂现象及解决方案 脑裂 形成脑裂的原因 解决脑裂的几种方法: 为了减少或避免HA集群中出现脑裂现象,我们可以采取以下措施: Keepalived服务主要功能࿰…...
软考高级之系统架构师之系统开发基础
架构 场景 场景(scenarios)在进行体系结构评估时,一般首先要精确地得出具体的质量目标,并以之作为判定该体系结构优劣的标准。为得出这些目标而采用的机制做场景。场景是从风险承担者的角度对与系统的交互的简短描述。在体系结构…...

Web 3.0 安全风险,您需要了解这些内容
随着技术的不断发展,Web 3.0 正在逐渐成为现实,为我们带来了许多新的机遇和挑战。然而,与任何新技术一样,Web 3.0 也伴随着一系列安全风险,这些风险需要被认真对待。在这篇文章中,我们将探讨一些与Web 3.0 …...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...