设计模式(C++)-行为型模式-责任链模式

设计模式(C++)-行为型模式-责任链模式

一、责任链模式概述

责任链模式(Chain of Responsibility Pattern):是一种行为型设计模式,允许你将请求沿着处理者链进行发送。每个处理者都可以决定是否处理请求以及是否将请求传递给链中的下一个处理者。
主要解决: 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
何时使用: 在处理消息的时候以过滤很多道。

二、责任链模式UML类图

责任链场景

编写程序完成学校OA系统的采购审批项目:需求:

  • 采购员采购教学器材
  • 如果金额 小于等于5000, 由教学主任审批
  • 如果金额 小于等于10000, 由院长审批
  • 如果金额 小于等于30000, 由副校长审批
  • 如果金额 超过30000以上,有校长审批

三、代码实现

cpp 复制代码
//chain.h
#pragma once
/*
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。
这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同
的请求传给下一个接收者,依此类推
**主要解决:**职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求
的发送者和请求的处理者解耦了。
**何时使用:**在处理消息的时候以过滤很多道。
举例:
编写程序完成学校OA系统的采购审批项目:需求:
- 采购员采购教学器材
- 如果金额 小于等于5000, 由教学主任审批
- 如果金额 小于等于10000, 由院长审批
- 如果金额 小于等于30000, 由副校长审批
- 如果金额 超过30000以上,有校长审批
*/
#include <iostream>
#include <string>
#include <memory>
using namespace std;
//购买请求类
class PurchaseRequest{
public:
	PurchaseRequest(const int type, const float price, const int id)
	: type(type),
		price(price),
		id(id)
	{
	}
	int getType()const;
	float getPrice()const;
	int getId()const;
private:
	//请求类型
	int type;
	//价格
	float price = 0.f;
	int id = 0;
};
//审批类
class Approver {
public:
	explicit Approver(const string&name) :m_name(name) {};
	void setApprover(Approver*const approver);
	//处理审批请求的方法,得到一个请求,处理是子类完成的,因此该方法写成纯虚方法
	virtual void processRequest(PurchaseRequest* purchaseRequest)=0;
protected:
	//下一个处理者
	Approver* nextApprover;
	string m_name;
};

//教学主任
class DepartmentApprover:public Approver
{
public:
	explicit DepartmentApprover(const string&name) :Approver(name) {}
	void processRequest(PurchaseRequest*purchaseRequest)override;
};

//院长
class CollegeApprover :public Approver {
public:
	explicit CollegeApprover(const string&name) :Approver(name) {}
	void processRequest(PurchaseRequest*purchaseRequest)override;
};

//副校长
class ViceSchoolMasterApprover:public Approver {
public:
	explicit ViceSchoolMasterApprover(const string&name) :Approver(name) {}
	void processRequest(PurchaseRequest*purchaseRequest)override;
};

//校长
class SchoolMasterApprover :public Approver {
public:
	explicit SchoolMasterApprover(const string&name) :Approver(name) {}
	void processRequest(PurchaseRequest*purchaseRequest)override;
};

void testChainOfResponsibility();
//chain.cc
#include "chain.h"
int PurchaseRequest::getType()const {
	return type;
}
float PurchaseRequest::getPrice()const {
	return price;
}
int PurchaseRequest::getId()const {
	return id;
}
void Approver::setApprover(Approver*const approver) {
	this->nextApprover = approver;
}
void DepartmentApprover::processRequest(PurchaseRequest* purchaseRequest)
{
	if (purchaseRequest->getPrice() <= 5000)
	{
		cout << "请求编号id=" << purchaseRequest->getId() << "被" << this->m_name << "处理" << endl;
	}
	else
	{
		nextApprover->processRequest(purchaseRequest);
	}
}

void CollegeApprover::processRequest(PurchaseRequest* purchaseRequest)
{
	if (purchaseRequest->getPrice() > 5000 && purchaseRequest->getPrice() <= 10000)
	{
		cout << "请求编号id=" << purchaseRequest->getId() << "被" << this->m_name << "处理" << endl;
	}
	else
	{
		nextApprover->processRequest(purchaseRequest);
	}
}
void ViceSchoolMasterApprover::processRequest(PurchaseRequest* purchaseRequest)
{
	if (purchaseRequest->getPrice() > 10000 && purchaseRequest->getPrice() <= 30000)
	{
		cout << "请求编号id=" << purchaseRequest->getId() << "被" << this->m_name << "处理" << endl;
	}
	else
	{
		nextApprover->processRequest(purchaseRequest);
	}
}
void SchoolMasterApprover::processRequest(PurchaseRequest* purchaseRequest)
{
	if (purchaseRequest->getPrice() > 30000)
	{
		cout << "请求编号id=" << purchaseRequest->getId() << "被" << this->m_name << "处理" << endl;
	}
	else
	{
		nextApprover->processRequest(purchaseRequest);
	}
}
void testChainOfResponsibility() {
	cout << "=================chain of responsibility begin===============" << endl;
	//创建一个请求
	std::unique_ptr<PurchaseRequest> purchaseRequest = std::make_unique<PurchaseRequest>(1, 1000, 1);
	std::unique_ptr<PurchaseRequest> purchaseRequest1 = std::make_unique<PurchaseRequest>(1, 30000, 2);
	//创建相关的审批人
	std::unique_ptr<DepartmentApprover> department = std::make_unique<DepartmentApprover>("张主任");
	std::unique_ptr <CollegeApprover > college = std::make_unique<CollegeApprover>("李院长");
	std::unique_ptr <ViceSchoolMasterApprover > viceSchoolMaster = std::make_unique<ViceSchoolMasterApprover>("王副校长");
	std::unique_ptr <SchoolMasterApprover > schoolMaster = std::make_unique<SchoolMasterApprover>("佟校长");
	//需要将各个审批级别的下一个人设置好(处理人构成一个环装就可以从任何一个人开始处理了)
	//否则必须从第一个处理人开始
	department->setApprover(college.get());
	college->setApprover(viceSchoolMaster.get());
	viceSchoolMaster->setApprover(schoolMaster.get());
	schoolMaster->setApprover(department.get());

	//开始处理请求
	viceSchoolMaster->processRequest(purchaseRequest.get());
	department->processRequest(purchaseRequest1.get());
	cout << "=================chain of responsibility end===============" << endl;
}

四、优缺点总结:

优点:

  • 降低耦合度:请求发送者无需知道具体处理者
  • 增强灵活性:可以动态添加或修改处理链
  • 简化对象:每个处理者只需关注自己的处理逻辑
  • 支持开闭原则:新增处理者无需修改现有代码

缺点:

  • 请求可能不被处理:如果链中没有合适的处理者
  • 性能影响:长处理链可能影响性能
  • 调试困难:请求的处理流程不够明确
  • 可能产生循环引用:需要注意智能指针的使用
相关推荐
xiaofeiyang1509 小时前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
qq_1998868711 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
汉克老师12 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者13 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
天若有情67313 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_1998868713 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao173383713 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
shada14 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
别动我齐刘海15 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
朝朝辞暮i16 小时前
C++第 2 课
c++