职责链模式(Chain Of Responsibility)的定义
(1)定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
①标准的职责链模式中,只要有对象处理了请求,这个请求就到此为至,不再被传递和处理了。
②但也可以变形使用职责链,就是让这个请求继续传递,每个职责对象对这个请求进行一定的功能处理,从而形成一个处理请求的功能链。
③当客户端发出请求,它并不知道谁会真正处理他的请求。在职责链模式中,请求不一定会被处理,因为可能没有合适的处理者,这里可以在职责链的末端加一个默认处理的职责对象。
④职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。
(2)职责链模式的结构和说明
①Handler:定义职责的接口,通常在这里定义处理请求的方法,可以在这里实现后继链(successor)。
②ConcreteHandler:实现职责的类,在这个类中,实现对它职责范围内请求的处理,如果不处理,就继续转发请求给后继者。
③Client:职责链的客户端,向链上的具体处理对象提交请求,让职责链负责处理。
【编程实验】HR系统中的请假审批流程
//声明文件
//行为型模式:职责链模式
//场景:请假条审批流程案例
//如果请假天数小于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;
}