当前位置:网站首页>责任链模式(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;
}
三、优缺点
优点
- 与链表一样,方便添加、删除、调整处理顺序。
- 每个处理者可以选择,是否将请求继续传递下去。
缺点
- 所有的处理者都需要实现统一的处理接口,也就意味着,处理着相同的输入。
边栏推荐
- Facebook社媒营销的5大技巧,迅速提高独立站转化率!
- jvm 二之 栈帧内部结构
- 技术管理三级跳
- Wuhan 2022 organizing of the high-performance computing added new ecological development of high-performance computing
- 【机器学习】实验2布置:基于回归分析的大学综合得分预测
- PWA 踩坑 - 第一次加载页面后无法获取CacheStorage某些资源
- Submit code process
- 论文《Deep Multifaceted Transformers for Multi-objective Ranking in Large-Scale E-commerce Recommender》
- 第06章 索引的数据结构【2.索引及调优篇】【MySQL高级】
- “蔚来杯“2022牛客暑期多校训练营5,签到题KBGHFCD
猜你喜欢
随机推荐
MySQL-FlinkCDC-Hudi实时入湖
(2022牛客多校五)D-Birds in the tree(树形DP)
【CV】OpenVINO安装教程
Leetcode Weekly 304
【机器学习】实验5布置:AAAI会议论文聚类分析
Redis 常用命令和基本数据结构(数据类型)
倍福使用AdsRemote组件实现和C#的ADS通讯
PMP新考纲通关秘籍,告别抓瞎
PMP新考纲考试内容介绍
【暑期每日一题】洛谷 P1192 台阶问题
Go 实现分布式锁
实验8 VLAN综合实验
实验7 MPLS实验
吃透Chisel语言.30.Chisel进阶之通信状态机(二)——FSMD:以Popcount为例
解决C#非静态字段、方法或属性“islandnum.Program.getIslandCount(int[][], int, int)”要求对象引用
See the picture to understand | How to choose sales indicators to measure the health of business growth
埋点开发流程
Summer Summary (3)
optional
【故障诊断分析】基于matlab FFT轴承故障诊断【含Matlab源码 2001期】









