当前位置:网站首页>责任链模式(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;
}
三、优缺点
优点
- 与链表一样,方便添加、删除、调整处理顺序。
- 每个处理者可以选择,是否将请求继续传递下去。
缺点
- 所有的处理者都需要实现统一的处理接口,也就意味着,处理着相同的输入。
边栏推荐
猜你喜欢

59:第五章:开发admin管理服务:12:MongoDB的使用场景;(非核心数据,数据量比较大的非核心数据,人脸照片等隐私的小文件;)

每周推荐短视频:为什么产品开发需要数字化?如何做到数字化?
![[npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir](/img/c5/2c42e26e577506573985b30669ca6c.png)
[npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir

HCIP day one

jvm 二之 栈帧内部结构

张驰咨询:企业实施精益管理的最大障碍,只把精益作为一种工具和方法

FaceBook社媒营销高效转化技巧分享

深度学习网络模型的改进与调整

Vscode connect to remote server "Acquiring the lock on the/home / ~ 'problem
![(Notes are not completed) [Graph Theory] Traversal of graphs](/img/1d/d2909dcfa0ab5c207005971a7b4a2d.gif)
(Notes are not completed) [Graph Theory] Traversal of graphs
随机推荐
Vscode connect to remote server "Acquiring the lock on the/home / ~ 'problem
59:第五章:开发admin管理服务:12:MongoDB的使用场景;(非核心数据,数据量比较大的非核心数据,人脸照片等隐私的小文件;)
【图像去噪】基于matlab双立方插值和稀疏表示图像去噪【含Matlab源码 2009期】
2022夏暑假每日一题(六)
【心电信号】基于matlab心率检测【含Matlab源码 1993期】
LeetCode Algorithm 1374. 生成每种字符都是奇数个的字符串
Clapper that can interact with the audience in real time
有趣的网站
【机器学习】实验2布置:基于回归分析的大学综合得分预测
你认同这个观点吗?大多数企业的数字化都只是为了缓解焦虑
PMP新考纲通关秘籍,告别抓瞎
Expert Insights | 3 ways to seize innovation opportunities in a downturn
分离轴定理SAT凸多边形精确碰撞检测
Revitalize rural circular economy and digital chain to link agricultural "ecological chain"
sql 远程访问链接服务器
[21天学习挑战赛——内核笔记](一)——设备树的概述(硬件、目标、效果、文件类型)
【暑期每日一题】洛谷 P3156 【深基15.例1】询问学号
jvm 二之 栈帧内部结构
正则表达式的理解学习
张驰咨询:企业实施精益管理的最大障碍,只把精益作为一种工具和方法