当前位置: 首页 > news >正文

设计模式之职责链模式(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、职责链模式的提出 在软件开发过程中&#xff0c;发送者经常发送一个数据请求给特定的接收者对象&#xff0c;让其对请求数据进行处理&#xff08;一个数据请求只能有一个对象对其处理&#xff09;。如果发送的每个数据请求指定特定的接收者&#xff0c; 将带来发送者与接收…...

CGAL Mesh(网格数据)布尔操作

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Mesh布尔操作是一种在三维计算机图形学中用于组合两个或多个网格(mesh)对象的方法。它可以将两个网格对象组合成一个新的对象,同时保留原始对象的拓扑结构和几何信息。Mesh布尔操作主要有以下三种类型: Union(…...

技术分享| WebRTC之SDP详解

一&#xff0c;什么是SDP WebRTC 是 Web Real-Time Communication&#xff0c;即网页实时通信的缩写&#xff0c;是 RTC 协议的一种Web实现&#xff0c;项目由 Google 开源&#xff0c;并和 IETF 和 W3C 制定了行业标准。 WebRTC是点对点通讯&#xff0c;他的通话建立需要交换…...

Flink Table API/SQL 多分支sink

背景 在某个场景中&#xff0c;需要从Kafka中获取数据&#xff0c;经过转换处理后&#xff0c;需要同时sink到多个输出源中(kafka、mysql、hologres)等。两次调用execute, 阿里云Flink vvr引擎报错&#xff1a; public static void main(String[] args) {final StreamExecuti…...

Vue3 中 导航守卫 的使用

在Vue 3中&#xff0c;导航守卫&#xff08;Navigation Guards&#xff09;用于在路由切换前后执行一些操作&#xff0c;例如验证用户权限、取消路由导航等。Vue 3中的导航守卫与Vue 2中的导航守卫略有不同。下面是Vue 3中导航守卫的使用方式&#xff1a; 全局前置守卫&#xf…...

云原生概论

云原生是一种新兴的技术趋势&#xff0c;它旨在将应用程序设计和部署方式从传统的基础设施转向云端。云原生应用程序是一种针对云环境进行优化的应用程序&#xff0c;能够充分利用云端提供的弹性和可扩展性。本文将探讨云原生的概念、优势、应用场景以及未来发展方向。 一、云…...

hive-sql

hive-常用SQL汇总 查看数据库 -- 查看所有的数据库 show databases; 使用默认的库 -- 下面的语句可以查看默认的库 use default ;查看某个库下的表 -- 查看所有的表 show tables ; -- 查看包含 stu的表 &#xff0c;这种是通配的方法来查看 show tables like *stu*; 查…...

Rspack 创建 vue2/3 项目接入 antdv(rspack.config.js 配置 less 主题)

一、简介 Rspack CLI 官方文档。 rspack.config.js 官方文档。 二、创建 vue 项目 创建项目&#xff08;文档中还提供了 Rspack 内置 monorepo 框架 Nx 的创建方式&#xff0c;根据需求进行选择&#xff09; # npm 方式 $ npm create rspacklatest# yarn 方式 $ yarn create…...

基于centos7完成docker服务的一些基础操作

目录 要求完成 具体操作 1.安装docker服务&#xff0c;配置镜像加速器 2.下载系统镜像&#xff08;Ubuntu、 centos&#xff09; 3.基于下载的镜像创建两个容器 &#xff08;容器名一个为自己名字全拼&#xff0c;一个为首名字字母&#xff09; 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能够生成非常绚丽界面&#xff0c;但有其局限性的&#xff0c;对于一些业务逻辑和复杂算法&#xff0c;比如低阶的网络编程如 QTcpSocket &#xff0c;多线程&#xff0c;又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等&#xff0c;在 QML 中要么不可…...

Ros noetic Move_base 相关状态位置的获取 实战使用教程

前言: 有一段时间没有更新,这篇文章是为了后续MPC路径跟踪算法开设的帖子用于更新我自己的思路,由于MPC算法,要镶嵌到整个导航任务中去,就绕不开这个move_base包中相关的参数设置和其中相关状态位置的获取和解读等等。 因为最近遇到小车在其他的环境中有些时候,不需要自己…...

【SpringBoot】SpringBoot项目与Vue对接接口的步骤

下面是SpringBoot项目与Vue对接接口的步骤&#xff1a; 创建SpringBoot项目&#xff0c;在项目中添加依赖&#xff0c;如Spring MVC、MyBatis等框架。 在SpringBoot项目中编写接口方法&#xff0c;使用注解标识请求方式&#xff0c;如GetMapping、PostMapping等&#xff0c;并…...

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&#xff0c;官网下载即可&#xff1a; MSYS2 安装其他的编译工具&#xff08;貌似不需要把中间的命令全部执行&#xff09;&#xff1a; MSYS2使用教程——win10系统64位安装msys2最新版&#xff08;msys2-x86_xxxx.exe&#xff09;_msys64_Dreamhai的博客-CSDN博…...

8月17日上课内容 第三章 LVS+Keepalived群集

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

Threejs学习05——球缓冲几何体背景贴图和环境贴图

实现随机多个三角形随机位置随机颜色展示效果 这是一个非常简单基础的threejs的学习应用&#xff01;本节主要学习的是球面缓冲几何体的贴图部分&#xff0c;这里有环境贴图以及背景贴图&#xff0c;这样可以有一种身临其境的效果&#xff01;这里环境贴图用的是一个.hdr的文件…...

LVS+Keepalived群集实验

目录 Keepalived 是什么 Keepalived 功能 Keepalived 模块 工作原理 脑裂现象及解决方案 脑裂 形成脑裂的原因 解决脑裂的几种方法&#xff1a; 为了减少或避免HA集群中出现脑裂现象&#xff0c;我们可以采取以下措施&#xff1a; Keepalived服务主要功能&#xff0…...

软考高级之系统架构师之系统开发基础

架构 场景 场景&#xff08;scenarios&#xff09;在进行体系结构评估时&#xff0c;一般首先要精确地得出具体的质量目标&#xff0c;并以之作为判定该体系结构优劣的标准。为得出这些目标而采用的机制做场景。场景是从风险承担者的角度对与系统的交互的简短描述。在体系结构…...

Web 3.0 安全风险,您需要了解这些内容

随着技术的不断发展&#xff0c;Web 3.0 正在逐渐成为现实&#xff0c;为我们带来了许多新的机遇和挑战。然而&#xff0c;与任何新技术一样&#xff0c;Web 3.0 也伴随着一系列安全风险&#xff0c;这些风险需要被认真对待。在这篇文章中&#xff0c;我们将探讨一些与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; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 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)。由于空间…...