《设计模式的艺术》笔记 - 职责链模式

介绍

        职责链模式避免将请求发送者与接收者耦合在一起,让多个对象都有机会接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>
#include <atomic>class Handler {
public:virtual void handleRequest(int req) = 0;void setNextHandler(Handler *handler);protected:Handler *m_next;
};class ConcreteHandlerA : public Handler {
public:void handleRequest(int req) override;
};class ConcreteHandlerB : public Handler {
public:void handleRequest(int req) override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"
#include <thread>
#include <unistd.h>void Handler::setNextHandler(Handler *handler) {m_next = handler;
}void ConcreteHandlerA::handleRequest(int req) {if (req < 100) {std::cout << "ConcreteHandlerA::handleRequest" << std::endl;} else if (m_next) {std::cout << "next" << std::endl;m_next->handleRequest(req);} else {std::cout << "no next" << std::endl;}
}void ConcreteHandlerB::handleRequest(int req) {if (req < 1000) {std::cout << "ConcreteHandlerB::handleRequest" << std::endl;} else if (m_next) {std::cout << "next" << std::endl;m_next->handleRequest(req);} else {std::cout << "no next" << std::endl;}
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Handler *handlerA = new ConcreteHandlerA();Handler *handlerB = new ConcreteHandlerB();handlerA->setNextHandler(handlerB);handlerA->handleRequest(10);handlerA->handleRequest(500);handlerA->handleRequest(1000);return 0;
}

总结

优点

        1. 职责链模式使得一个对象无须知道是其他哪一个对象处理其请求。对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构。由客户端负责链的创建,降低了系统的耦合度。

        2. 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。

        3. 在给对象分派职责时,职责链可以提供更多的灵活性,可以通过在运行时对链进行动态的增加或修改来增加或改变处理一个请求的职责。

        4. 在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需要在客户端重新建链即可,从这一点来看是符合开闭原则的。

缺点

        1. 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理。一个请求也可能因职责链没有被正确配置而得不到处理。

        2. 对于比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。

        3. 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。

适用场景

        1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定。客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。

        2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

        3. 可动态指定一组对象处理请求。客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。

练习

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>
#include <atomic>class Handler {
public:virtual void handleRequest(int req) = 0;void setNextHandler(Handler *handler);protected:Handler *m_next;
};class Director : public Handler {
public:void handleRequest(int req) override;
};class Manager : public Handler {
public:void handleRequest(int req) override;
};class GeneralManager : public Handler {
public:void handleRequest(int req) override;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"
#include <thread>
#include <unistd.h>void Handler::setNextHandler(Handler *handler) {m_next = handler;
}void Director::handleRequest(int req) {if (0 < req && req < 3) {std::cout << "请假" << req << "天,主任审批通过" << std::endl;} else if (m_next) {m_next->handleRequest(req);} else {std::cout << "请假" << req << "天,审批不通过" << std::endl;}
}void Manager::handleRequest(int req) {if (3 <= req && req < 10) {std::cout << "请假" << req << "天,经理审批通过" << std::endl;} else if (m_next) {m_next->handleRequest(req);} else {std::cout << "请假" << req << "天,审批不通过" << std::endl;}
}void GeneralManager::handleRequest(int req) {if (10 <= req && req < 30) {std::cout << "请假" << req << "天,总经理审批通过" << std::endl;} else if (m_next) {m_next->handleRequest(req);} else {std::cout << "请假" << req << "天,审批不通过" << std::endl;}
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {Handler *director = new Director();Handler *manager = new Manager();Handler *general = new GeneralManager();director->setNextHandler(manager);manager->setNextHandler(general);director->handleRequest(2);director->handleRequest(5);director->handleRequest(15);director->handleRequest(30);delete general;delete manager;delete director;return 0;
}

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

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

相关文章

【算法Hot100系列】跳跃游戏

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

windows系统中,通过LOAD到入csv格式的文件到neo4j中,如何写文件路径

在Neo4j中&#xff0c;使用LOAD CSV语句导入CSV文件时&#xff0c;需要确保你的文件路径是正确的。如果你使用的是Neo4j Desktop或者Neo4j Server&#xff0c;通常需要将CSV文件放在特定的导入目录下。 例如&#xff0c;如果你使用的是Neo4j Desktop&#xff0c;通常会有一个默…

Linux搭建dns主从服务器

一、实验要求 配置Dns主从服务器&#xff0c;能够实现正常的正反向解析 二、知识点 1、DNS简介 DNS&#xff08;Domain Name System&#xff09;是互联网上的一项服务&#xff0c;它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便的访问互联网。…

js的节流和防抖

在JavaScript中&#xff0c;节流&#xff08;Throttling&#xff09;和防抖&#xff08;Debouncing&#xff09;是两种常用的优化高频率触发的事件或函数调用的技术。 防抖&#xff08;Debouncing&#xff09;&#xff1a; 防抖的基本思想是&#xff1a;一定时间内&#xff0…

【DP】LCR 100.三角形最小路径和

题目 法1&#xff1a;DP class Solution {public int minimumTotal(List<List<Integer>> triangle) {int n triangle.size();if (n 1) {return triangle.get(0).get(0);}int[] tmp new int[n];tmp[0] triangle.get(0).get(0);int ans Integer.MAX_VALUE;for…

磁的基本知识

磁的基本知识。 一、磁铁及其基本性质。 1、磁铁的概念。 具有吸引铁、钴、镍等金属能力的物质叫做磁体&#xff0c;俗称磁铁、吸铁石。被吸引的铁、钴、镍等物质叫做铁磁性材料。磁铁吸引铁磁性材料的性质叫做磁性。 2、磁铁的分类。 磁铁可分为天然磁铁和人造磁铁两种。天然…

准备注销CSDN了,再也不用了

动不动就是“外包干了2个月&#xff0c;技术明显…”推荐在首页&#xff0c;看到就烦&#xff0c;彻彻底底的垃圾堆&#xff0c;一个相同的标题滑不到底&#xff0c;点进去就是面试题、推销&#xff0c;牛头不对马嘴&#xff0c;真垃圾&#xff08;画个圈圈&#xff09;&#x…

C语言再学习 -- C语言搭建TCP服务器/客户端

TCP/UDP讲过~ 参看&#xff1a;UNIX再学习 – TCP/UDP 客户机/服务器 参看&#xff1a;UNIX再学习 – 网络IPC&#xff1a;套接字 这里记录一下可用的TCP服务器和客户端代码。 参看&#xff1a;用C语言搭建TCP服务器/客户端 一、TCP服务器 #include <stdio.h> #includ…

postman导入https证书

进入setting配置中Certificates配置项 点击“Add Certificate”,然后配置相关信息 以上配置完毕&#xff0c;如果测试出现“SSL Error:Self signed certificate” 则将“SSL certificate verification”取消勾选

uni-app使用HBuilderX打包Web项目

非常简单&#xff0c;就是容易忘记 一、找到manifest.json配置Web配置 二、源码视图配置 "h5" : {"template" : "","domain" : "xxx.xx.xx.xxx","publicPath" : "./","devServer" : {&quo…

C# tcp客户端字符串(图片名称)+ 图片数据打包,发送到服务端;服务端接收到数据后解析数据包

在C#中&#xff0c;要将字符串和图片数据打包发送到服务端&#xff0c;并在服务端解析这些数据&#xff0c;可以按照以下步骤进行&#xff1a; 客户端打包数据 1、创建一个自定义的数据结构来保存字符串和图片数据。 2、将字符串转换为字节数组。 3、将图片数据转换为字节数组。…

01 MyBatisPlus快速入门

1. MyBatis-Plus快速入门 版本 3.5.31并非另起炉灶 , 而是MyBatis的增强 , 使用之前依然要导入MyBatis的依赖 , 且之前MyBatis的所有功能依然可以使用.局限性是仅限于单表操作, 对于多表仍需要手写 项目结构&#xff1a; 先导入依赖&#xff0c;比之前多了一个mybatis-plus…

学习python仅收藏此一篇就够了(闭包,装饰器)

闭包 在函数嵌套的前提下&#xff0c;内部函数使用了外部函数的变量&#xff0c;并且外部函数返回了内部函数&#xff0c;我们把这个使用外部函数变量的内部函数称为闭包。 简单闭包 内部函数使用外部变量 def outer(name):def inner(name1):print(f"<{name}>&l…

x-cmd pkg | aliyun - 阿里云 CLI

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 aliyun 是基于阿里云 OpenAPI 的管理工具&#xff0c;用于与阿里云服务交互&#xff0c;管理阿里云资源。 首次用户 使用 x env use aliyun 即可自动下载并使用 在终端运行 eval "$(curl https://get.x-cmd.com…

Jetson之路

119换源之觞&#xff1a;版本一定要对耶耶耶&#xff01;所有问题解决&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;Ubuntu20.04 错误提醒&#xff1a;无法修正错误_aptitude : 依赖: libapt-pkg5.0 (> 1…

(初研) Sentence-embedding fine-tune notebook

由于工作需要&#xff0c;需要对embedding模型进行微调&#xff0c;我调用了几种方案&#xff0c;都比较繁琐。先记录一个相对简单的方案。以下内容并不一定正确&#xff0c;请刷到的大佬给予指正&#xff0c;不胜感激&#xff01;&#xff01;&#xff01; 一.对BGE模型&…

qt学习:实战 读取txt文件+定时器点名

目录 目标 步骤 头文件 配置ui界面 在.h里定义槽函数和字符串链表和定时器指针 在构造函数里读取txt文件并初始化定时器 开始按钮点击函数 开始定时器 停止按钮点击函数 关闭定时器 定时器槽函数 目标 两个按钮&#xff0c;一个开始点名&#xff0c;一个停止点名一个…

字符串倒序输出

近期面试有这样一个问题&#xff0c;给定一个字符串&#xff0c;将其倒序输出&#xff0c;这种问题乍一看很好处理&#xff0c;但是实际在写的时候不知道怎么写了&#xff0c;有思路&#xff0c;但是没写出来。记录一下。 字符串反转实现的方式有多种&#xff0c;本质思想是将两…

HTML动态房屋装饰特效

下面是代码&#xff1a; <!DOCTYPE html> <html lang"en" ><head><meta charset"UTF-8"><title>HTML5房屋装饰工具DEMO演示</title><link rel"stylesheet" href"css/style.css"></he…

数字化金融时代:探讨全球金融科技创新的最新动态

在当今数字化金融时代&#xff0c;金融科技创新如影随形&#xff0c;迅猛发展。本文将深入探讨全球范围内金融科技的最新动态&#xff0c;剖析各地新兴趋势与突破。从区块链技术的应用到人工智能在金融领域的崭露头角&#xff0c;我们将一一解读这个正在不断演变的金融科技画卷…