当前位置:网站首页>责任链模式(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;
}
三、优缺点
优点
- 与链表一样,方便添加、删除、调整处理顺序。
- 每个处理者可以选择,是否将请求继续传递下去。
缺点
- 所有的处理者都需要实现统一的处理接口,也就意味着,处理着相同的输入。
边栏推荐
猜你喜欢
“蔚来杯“2022牛客暑期多校训练营5,签到题KBGHFCD
Redis 常用命令和基本数据结构(数据类型)
[Dataset][VOC] Male and female dataset voc format 6188 sheets
[npm install error report collection] - npm ERR! code ENOTEMPTY npm ERR! syscall rmdir
59:第五章:开发admin管理服务:12:MongoDB的使用场景;(非核心数据,数据量比较大的非核心数据,人脸照片等隐私的小文件;)
(2022牛客多校五)D-Birds in the tree(树形DP)
文件上传漏洞(二)
Facebook社媒营销的5大技巧,迅速提高独立站转化率!
根据一个字段的内容去更新另一个字段的数据,这样的sql语句该怎么样书写
实例032:反向输出II
随机推荐
张驰咨询:企业实施精益管理的最大障碍,只把精益作为一种工具和方法
【ROS基础】map、odom、base_link、laser 的理解 及其 tf 树的理解
Submit code process
Redis 常用命令和基本数据结构(数据类型)
埋点开发流程
【暑期每日一题】洛谷 P1255 数楼梯
Specified URL is not reachable,caused by :‘Read timed out
修改apt-get源为国内镜像源
Swagger的简单介绍,集成,以及如何在生产环境中关闭swagger,在测试和开发环境中自动打开
mysql 注入
暑假第五周总结
(2022牛客多校五)B-Watches(二分)
59:第五章:开发admin管理服务:12:MongoDB的使用场景;(非核心数据,数据量比较大的非核心数据,人脸照片等隐私的小文件;)
Expert Insights | 3 ways to seize innovation opportunities in a downturn
【机器学习】实验1布置:基于决策树的英雄联盟游戏胜负预测
每周推荐短视频:为什么产品开发需要数字化?如何做到数字化?
结构体大小计算--结构体内存对齐
C# FileInfo class
21 days learning challenge 】 【 sequential search
Wuhan 2022 organizing of the high-performance computing added new ecological development of high-performance computing