当前位置:网站首页>责任链模式(Chain Of Responsibility)
责任链模式(Chain Of Responsibility)
2022-08-02 06:54:00 【baboon_chen】
参考:
design-patterns-cpp/Proxy.cpp at master · JakubVojvoda/design-patterns-cpp · GitHub
一、什么是责任链模式?
定义:将用户的请求,通过拆解,传递给多处理者按顺序处理。它们有相同的输入,且每个处理者中都包含下一个处理者对象(最后一个处理者可以没有后继),像链表一样有者先后顺序。这样,可以通过调整链表的结构来改变请求的处理流程。
比如,员工报销需要找组长、经理、部长、账务行签字,特殊时期想简化报销流程,可以去除组长、经理等审批环节;或者审批到经理就没有通过,也就不需要走后续流程。甚至还可以添加其它审批环节,但要求所有的审批者都有相同的输入,就是审批单。

二、实现
责任链(Chain Of Responsibility)模式包含以下主要角色:
- 处理者 (Handler):声明了所有具体处理者的通用接口。 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法。
- 基础处理者 (Base Handler):是一个可选的类, 你可以将所有处理者共用的样本代码放置在其中。
通常情况下, 该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。 该类还可以实现默认的处理行为: 确定下个处理者存在后再将请求传递给它。- 具体处理者 (Concrete Handlers):包含处理请求的实际代码。 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
处理者通常是独立且不可变的, 需要通过构造函数一次性地获得所有必要地数据。
/*
* C++ Design Patterns: Chain of Responsibility
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
* 2016
*
* Source code is licensed under MIT License
* (for more details see LICENSE)
*
*/
#include <iostream>
/*
* 处理者 (Handler):声明了所有具体处理者的通用接口。
* 该接口通常仅包含单个方法用于请求处理, 但有时其还会包含一个设置链上下个处理者的方法
*/
class Handler
{
public:
virtual ~Handler() {}
virtual void setHandler( Handler *s )
{
successor = s;
}
virtual void handleRequest()
{
if (successor != 0)
{
successor->handleRequest();
}
}
// ...
private:
Handler *successor;
};
/*
* 具体处理者 (Concrete Handlers):包含处理请求的实际代码。
* 每个处理者接收到请求后, 都必须决定是否进行处理, 以及是否沿着链传递请求。
*/
class ConcreteHandler1 : public Handler
{
public:
~ConcreteHandler1() {}
bool canHandle()
{
// ...
return false;
}
virtual void handleRequest()
{
if ( canHandle() )
{
std::cout << "Handled by Concrete Handler 1" << std::endl;
}
else
{
std::cout << "Cannot be handled by Handler 1" << std::endl;
Handler::handleRequest();
}
// ...
}
// ...
};
class ConcreteHandler2 : public Handler
{
public:
~ConcreteHandler2() {}
bool canHandle()
{
// ...
return true;
}
virtual void handleRequest()
{
if ( canHandle() )
{
std::cout << "Handled by Handler 2" << std::endl;
}
else
{
std::cout << "Cannot be handled by Handler 2" << std::endl;
Handler::handleRequest();
}
// ...
}
// ...
};
int main()
{
ConcreteHandler1 handler1;
ConcreteHandler2 handler2;
handler1.setHandler( &handler2 );
handler1.handleRequest();
return 0;
}
三、优缺点
优点
- 与链表一样,方便添加、删除、调整处理顺序。
- 每个处理者可以选择,是否将请求继续传递下去。
缺点
- 所有的处理者都需要实现统一的处理接口,也就意味着,处理着相同的输入。
边栏推荐
- Clapper that can interact with the audience in real time
- 以训辅教,以战促学 | 新版攻防世界平台正式上线运营!
- [npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
- 分离轴定理SAT凸多边形精确碰撞检测
- [21天学习挑战赛——内核笔记](一)——设备树的概述(硬件、目标、效果、文件类型)
- Connection reset by peer 问题解析
- 【机器学习】实验3布置:贝叶斯垃圾邮件识别
- 自然语言处理 文本预处理(上)(分词、词性标注、命名实体识别等)
- 21 days learning challenge 】 【 sequential search
- 【心电信号】基于matlab心率检测【含Matlab源码 1993期】
猜你喜欢

实例030:回文数

解决:- SPY: No data found for this date range, symbol may be delisted报错

Gradle系列——Gradle插件(基于Gradle文档7.5)day3-2

Vscode连接远程服务器出现‘Acquiring lock on/home/~’问题

yml字符串读取时转成数字了怎么解决
![[Dataset][VOC] Eyewear dataset 6000 in VOC format](/img/66/37f76d9ce5d5f68d6ea0e18710fa04.png)
[Dataset][VOC] Eyewear dataset 6000 in VOC format
![带手续费买卖股票的最大利益[找DP的状态定义到底缺什么?]](/img/14/cd6ed7452230571db2e027f61dbdba.png)
带手续费买卖股票的最大利益[找DP的状态定义到底缺什么?]

2022.07.31(LC_6132_使数组中所有元素都等于零)

每周推荐短视频:为什么产品开发需要数字化?如何做到数字化?

Leetcode Weekly 304
随机推荐
MySQL-FlinkCDC-Hudi实时入湖
结构体大小计算--结构体内存对齐
C#重点问题之Struct和Class的异同
【机器学习】实验1布置:基于决策树的英雄联盟游戏胜负预测
【暑期每日一题】洛谷 P3156 【深基15.例1】询问学号
Project development specification
实例029:反向输出
[Dataset][VOC] Male and female dataset voc format 6188 sheets
C# FileInfo class
[21天学习挑战赛——内核笔记](一)——设备树的概述(硬件、目标、效果、文件类型)
yml字符串读取时转成数字了怎么解决
入门opencv,欢笑快乐每一天
File upload vulnerability (2)
PMP新考纲考试内容介绍
MQ带来的一些问题、及解决方案
Submit code process
【心电信号】基于matlab心率检测【含Matlab源码 1993期】
【CV】OpenVINO安装教程
实例030:回文数
【红队】ATT&CK - 创建或修改系统进程实现持久化(更新ing)