欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Behavior.ResponsibilityChain职责链模式:义务之内的处理,权力之外的递交

程序员文章站 2022-05-26 08:39:37
...
职责链模式(Chain Of Responsibility)的定义

(1)定义

  使多个对象都有机会处理请求,从而避免请求的发送者接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

  ①标准的职责链模式中,只要有对象处理了请求,这个请求就到此为至,不再被传递和处理了。

  ②但也可以变形使用职责链,就是让这个请求继续传递,每个职责对象对这个请求进行一定的功能处理,从而形成一个处理请求的功能链。

  ③当客户端发出请求,它并不知道谁会真正处理他的请求。在职责链模式中,请求不一定会被处理,因为可能没有合适的处理者,这里可以在职责链的末端加一个默认处理的职责对象。

  ④职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。

(2)职责链模式的结构和说明

Behavior.ResponsibilityChain职责链模式:义务之内的处理,权力之外的递交

  ①Handler:定义职责的接口,通常在这里定义处理请求的方法,可以在这里实现后继链(successor)

  ②ConcreteHandler:实现职责的类,在这个类中,实现对它职责范围内请求的处理,如果不处理,就继续转发请求给后继者。

  ③Client:职责链的客户端,向链上的具体处理对象提交请求,让职责链负责处理。

【编程实验】HR系统中的请假审批流程

Behavior.ResponsibilityChain职责链模式:义务之内的处理,权力之外的递交


//声明文件

//行为型模式:职责链模式
//场景:请假条审批流程案例
//如果请假天数小于3天,主任审批
//如果请假天数大于等于3天,小于10天,经理审批
//如果大于等于10天,小天30天,总经理审批
//如果大于等于30天,提示拒绝
#include <iostream>
#include <string>
using namespace std;



//***************************辅助类*****************
//请假条
class CLeaveRequest{
private:
	string strEmp; //请假员工
	int iDays;//请假天数
	string strReason; //请假原因
public:
	CLeaveRequest(string emp, int days, string reason);
	void SetEmp(string emp);
	string GetEmp();
	void SetDays(int days);
	int GetDays();
	void SetReason(string reason);
	string GetReason();
};

//***************************抽象职责类*************
class CLeader{
protected:
	string strName;//领导姓名
	CLeader* pUpLeader;//职责链上的后继对象
public:
	CLeader(string name);
	void SetUpLeader(CLeader* leader);
	virtual void LeaveRespond(CLeaveRequest* request) = 0;
};

//***********************具体职责实现类**************************
//主任
class CDirector : public CLeader{
public:
	CDirector(string name);
	void LeaveRespond(CLeaveRequest* request);
};
//经理
class CManager : public CLeader{
public:
	CManager(string name);
	void LeaveRespond(CLeaveRequest* request);
};

//总经理
class CBoss : public CLeader{
public:
	CBoss(string name);
	void LeaveRespond(CLeaveRequest* request);
};

//实现文件

#include "StdAfx.h"
#include "ResponsibilityChain.h"



//***************************辅助类*****************
//请假条
CLeaveRequest::CLeaveRequest(string emp, int days, string reason)
{
	strEmp = emp; iDays = days; strReason = reason;
}
void CLeaveRequest::SetEmp(string emp){strEmp = emp;}
string CLeaveRequest::GetEmp(){return strEmp;}
void CLeaveRequest::SetDays(int days){iDays = days;}
int CLeaveRequest::GetDays(){return iDays;}
void CLeaveRequest::SetReason(string reason){strReason = reason;}
string CLeaveRequest::GetReason(){return strReason;}

//***************************抽象职责类*************
CLeader::CLeader(string name){strName = name; pUpLeader = NULL;}
void CLeader::SetUpLeader(CLeader* leader){pUpLeader = leader;}

//***********************具体职责实现类**************************
//主任
CDirector::CDirector(string name) : CLeader(name){}
void CDirector::LeaveRespond(CLeaveRequest* request){
	if(request->GetDays() < 3)				cout << "领导" << strName << "批准了员工" << request->GetEmp() << request->GetDays() << "天假" << endl;
	else if(pUpLeader != NULL)			pUpLeader->LeaveRespond(request);
}
//经理
CManager::CManager(string name) : CLeader(name){}
void CManager::LeaveRespond(CLeaveRequest* request){
	if(request->GetDays() >= 3 && request->GetDays() < 10)			cout << "领导" << strName << "批准了员工" << request->GetEmp() << request->GetDays() << "天假" << endl;
	else if(pUpLeader != NULL)			pUpLeader->LeaveRespond(request);
}

//总经理
CBoss::CBoss(string name) : CLeader(name){}
void CBoss::LeaveRespond(CLeaveRequest* request){
	if(request->GetDays() >= 10 && request->GetDays() < 30)			cout << "领导" << strName << "批准了员工" << request->GetEmp() << request->GetDays() << "天假" << endl;
	else																								cout << "领导" << strName << "驳回了员工" << request->GetEmp() << request->GetDays() << "天假【请假时间过长】" << endl;
}

//测试客户端

void main()
{
	CLeader* pDirector = new CDirector("ZhangSan");
	CLeader* pManager = new CManager("LiSi");
	CLeader* pBoss = new CBoss("WangWu");

	//组织职责链对象的关系
	pDirector->SetUpLeader(pManager); pManager->SetUpLeader(pBoss);
	CLeaveRequest oRequest("Tom", 15, "go home !");//开始请假操作
	pDirector->LeaveRespond(&oRequest);

	delete pDirector; delete pManager; delete pBoss;
}