设计模式实现(二十)---职责链模式(Chain of Responsibility)

本文介绍了职责链模式的概念及其应用场景,通过两个实例详细展示了如何利用职责链模式降低对象间的耦合度,实现请求处理的灵活配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

职责连模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。这里发出这个请求的客户端并不知道这当中的哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态地重新组织和分配责任。


#include <iostream>
#include <string>
using namespace std;
//Hander类,定义一个处理请求的接口。
class Handler
{

protected:
	Handler *successor;
public:
		string type;
public:
	void SetSuccessor(Handler *successor)
	{
		this->successor = successor;
	}
	virtual void HandlerRequest(int request) = 0;
};

//ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继者。
//ConcreteHandler1,当请求数在0--10之间则有权处理,否则转到下一位。
class ConcreteHandler1 : public Handler
{
public:
	void HandlerRequest(int request)
	{
		type = "ConcreteHandler1";
		if(request >= 0 && request <10)
		{
			cout << type <<"处理请求:" << request<<endl;
		}
		else if(successor != NULL)
		{
			successor->HandlerRequest(request);
		}
	}
};

//ConcreteHandler2,当请求数在10--20之间则有权处理,否则转到下一位。
class ConcreteHandler2 : public Handler
{
public:
	void HandlerRequest(int request)
	{
		type = "ConcreteHandler2";
		if(request >= 10 && request <20)
		{
			cout << type <<"处理请求:" << request<<endl;
		}
		else if(successor != NULL)
		{
			successor->HandlerRequest(request);
		}
	}
};

//ConcreteHandler3,当请求数在20--30之间则有权处理,否则转到下一位。
class ConcreteHandler3 : public Handler
{
public:
	void HandlerRequest(int request)
	{
		type = "ConcreteHandler3";
		if(request >= 20 && request <30)
		{
			cout << type <<"处理请求:" << request<<endl;
		}
		else if(successor != NULL)
		{
			successor->HandlerRequest(request);
		}
	}
};

//客户端代码,向链上的具体处理对象提交请求
int main()
{
	ConcreteHandler1 h1;
	ConcreteHandler2 h2;
	ConcreteHandler3 h3;

	h1.SetSuccessor(&h2);
	h2.SetSuccessor(&h3);

	int requests[8] = {2,5,14,22,18,3,27,20};
	
	for(int i = 0;i<8;i++)
	{
		h1.HandlerRequest(requests[i]);
	}
	return 1;
}

着当中最关键的是当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这样使得接收者和放松着都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它锁有的候选接收者的引用。由于是在客户端来定义链的结构,也就是说,我可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。不过要当心,一个请求基友可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。需要考虑全面。

下面我们来看一个加薪和请假的例子。

#include <iostream>
#include <string>
using namespace std;
//申请
class Request
{
public:
	string requestType;
	string requestContent;
	int requestNum;
};
//管理者
class Manager
{
protected:
	string name;
	//上级
	Manager *superior;
public:
	Manager(string name)
	{
		this->name = name;
	}
	//设置管理者的上级
	void SetSuperior(Manager *superior)
	{
		this->superior = superior;
	}
	//申请请求
	virtual void RequestApplications(Request *request) = 0;
};

//经理类就可以去继承这个“管理者类”,只需要重写申请请求的方法就可以了
//经理
class CommonManager : public Manager
{
public:
	CommonManager(string name) : Manager(name){}
public:
	void RequestApplications(Request *request)
	{
		if(request->requestType == "请假" && request->requestNum < 3)
		{
			cout << name << ":" << request->requestContent << "数量"<<request->requestNum << "。被批准" << endl;
		}
		else
		{
			if(superior != NULL)
			{
				superior->RequestApplications(request);
			}
		}
	}
};
//总监,也是管理者
class Majordomo : public Manager
{
public:
	Majordomo(string name) : Manager(name){}
public:
	void RequestApplications(Request *request)
	{
		if(request->requestType == "请假" && request->requestNum < 6)
		{
			cout << name << ":" << request->requestContent << "数量"<<request->requestNum << "。被批准" << endl;
		}
		else
		{
			if(superior != NULL)
			{
				superior->RequestApplications(request);
			}
		}
	}
};

//总经理
class GeneralManager : public Manager
{
public:
	GeneralManager(string name) : Manager(name){}
public:
	void RequestApplications(Request *request)
	{
		if(request->requestType == "请假")
		{
			cout << name << ":" << request->requestContent << "数量"<<request->requestNum << "。被批准" << endl;
		}
		else if(request->requestType == "加薪" &&  request->requestNum <= 500)
		{
			cout << name << ":" << request->requestContent << "数量"<<request->requestNum << "。被批准" << endl;
		}
		else if(request->requestType == "加薪" &&  request->requestNum > 500)
		{
			cout << name << ":" << request->requestContent << "数量"<<request->requestNum << "。未批准" << endl;
		}
	}
};
int main()
{
	CommonManager jinli("金莉");
	Majordomo zongjian("综见");
	GeneralManager zhongjingli("宗精离");
	jinli.SetSuperior(&zongjian);
	zongjian.SetSuperior(&zhongjingli);

	Request request;
	request.requestContent = "小菜请假";
	request.requestType = "请假";
	request.requestNum = 2;
	//客户端的申请都是由经理发出,但实际上决策由谁来处理,客户端不知道。
	jinli.RequestApplications(&request);

	
	Request request1;
	request1.requestContent = "小菜请假";
	request1.requestType = "请假";
	request1.requestNum = 4;
	jinli.RequestApplications(&request1);
	
	Request request2;
	request2.requestContent = "小菜请求加薪";
	request2.requestType = "加薪";
	request2.requestNum = 500;
	jinli.RequestApplications(&request2);

	Request request3;
	request3.requestContent = "小菜请求加薪";
	request3.requestType = "加薪";
	request3.requestNum = 1500;
	jinli.RequestApplications(&request3);

	return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值