职责链模式(Chain of Responsibility):使用多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一个链,并沿着链传递请求,直到有一个对象处理它为止。
职责链模式最常见是在办公OA的请假流程中较为典型。接下来简单看下请假申请流程职责链模式的结构图:
代码结构如下:
- respond.h
#pragma once
#include <string>
class RespondRecord
{
private:
std::string m_strPosition;
std::string m_strName;
std::string m_strContent;
public:
RespondRecord(std::string partment, std::string name);
~RespondRecord();
void SetContent(std::string content);
void Request();
};
class RespondManager
{
protected:
std::string m_strPosition;
std::string m_strName;
RespondManager* m_pRespondManager;
public:
RespondManager(std::string position, std::string name);
virtual ~RespondManager();
void SetManager(RespondManager* pRespondManager);
void DealRespond(RespondRecord* pRespondRecord);
virtual void Respond() = 0;
};
class DepartManager : public RespondManager
{
public:
DepartManager(std::string position, std::string name);
~DepartManager();
void Respond();
private:
};
class HRManager : public RespondManager
{
public:
HRManager(std::string position, std::string name);
~HRManager();
private:
// 通过 RespondManager 继承
virtual void Respond() override;
};
class LeaderManager : public RespondManager
{
public:
LeaderManager(std::string position, std::string name);
~LeaderManager();
private:
// 通过 RespondManager 继承
virtual void Respond() override;
};
- respond.cpp
#include "respond.h"
#include <iostream>
RespondRecord::RespondRecord(std::string position, std::string name)
{
m_strPosition = position;
m_strName = name;
}
RespondRecord::~RespondRecord()
{
}
void RespondRecord::SetContent(std::string content)
{
m_strContent = content;
}
void RespondRecord::Request()
{
std::cout << "姓名:" << m_strName << " " << "职务:" << m_strPosition << std::endl;
std::cout << "申请内容:" << m_strContent << std::endl;
}
RespondManager::RespondManager(std::string position, std::string name)
{
m_strPosition = position;
m_strName = name;
m_pRespondManager = nullptr;
}
RespondManager::~RespondManager()
{
}
void RespondManager::SetManager(RespondManager * pRespondManager)
{
m_pRespondManager = pRespondManager;
}
void RespondManager::DealRespond(RespondRecord* pRespondRecord)
{
pRespondRecord->Request();
std::cout << "姓名:" << m_strName << " " << "职务:" << m_strPosition << std::endl;
Respond();
if (m_pRespondManager != nullptr)
{
m_pRespondManager->DealRespond(pRespondRecord);
}
}
DepartManager::DepartManager(std::string position, std::string name)
:RespondManager(position, name)
{
}
DepartManager::~DepartManager()
{
}
void DepartManager::Respond()
{
std::cout << "批示结果:通过" << std::endl;
}
HRManager::HRManager(std::string position, std::string name)
:RespondManager(position, name)
{
}
HRManager::~HRManager()
{
}
void HRManager::Respond()
{
std::cout << "批示结果:通过" << std::endl;
}
LeaderManager::LeaderManager(std::string position, std::string name)
:RespondManager(position, name)
{
}
LeaderManager::~LeaderManager()
{
}
void LeaderManager::Respond()
{
std::cout << "批示结果:通过" << std::endl;
}
调用方法:
#include "respond.h"
#include <iostream>
int main()
{
RespondRecord respondRecord("职员", "小菜");
respondRecord.SetContent("请假三天");
DepartManager departManger("软件部经理", "小生");
HRManager hrManager("人事经理", "小红");
LeaderManager leaderManager("软件部总监", "小红");
departManger.SetManager(&hrManager);
hrManager.SetManager(&leaderManager);
departManger.DealRespond(&respondRecord);
std::getchar();
return 0;
}
显示结果:
姓名:小菜 职务:职员
申请内容:请假三天
姓名:小生 职务:软件部经理
批示结果:通过
姓名:小菜 职务:职员
申请内容:请假三天
姓名:小红 职务:人事经理
批示结果:通过
姓名:小菜 职务:职员
申请内容:请假三天
姓名:小红 职务:软件部总监
批示结果:通过