设计模式(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;
}

四、优缺点总结:

优点:

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

缺点:

  • 请求可能不被处理:如果链中没有合适的处理者
  • 性能影响:长处理链可能影响性能
  • 调试困难:请求的处理流程不够明确
  • 可能产生循环引用:需要注意智能指针的使用
相关推荐
大袁同学1 小时前
【进程间通信】:洞穿边界修管道,映射内存渡进程
linux·c++·管道·进程间通信·ipc
Rabitebla2 小时前
【C++】string 类:原理、踩坑与对象语义
linux·c语言·数据结构·c++·算法·github·学习方法
邪修king2 小时前
UE5 零基础入门第四弹:UMG UI 系统入门,从静态界面到逻辑联动
c++·ui·ue5
CN-Dust3 小时前
【C++】输入cin例题专题
java·c++·算法
geovindu4 小时前
go: Visitor Pattern
开发语言·设计模式·golang·访问者模式
智者知已应修善业11 小时前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
智者知已应修善业13 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
徐某人..15 小时前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm