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

四、优缺点总结:

优点:

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

缺点:

  • 请求可能不被处理:如果链中没有合适的处理者
  • 性能影响:长处理链可能影响性能
  • 调试困难:请求的处理流程不够明确
  • 可能产生循环引用:需要注意智能指针的使用
相关推荐
见过夏天24 分钟前
C++ 基础入门完全指南
c++
胡萝卜术8 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
亦暖筑序1 天前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境2 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境2 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴3 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
青禾网络3 天前
Web 前端如何接入 AI 音效生成:从零到可用的完整方案
人工智能·设计模式
ZJPRENO4 天前
吃透软件开发六大设计原则,告别烂代码
设计模式