责任链模式(Chain of Responsibility Pattern)中,有一条由请求处理者对象组成的链条,每个对象(除最后一个对象外)都持有下一个对象的引用,请求发送者将请求发送给第一个对象,请求就会顺着链条走下去,直到有对象能够处理请求。该模式将多个处理者对象解耦,使得请求发送者只管将请求发送给责任链的第一个对象就是了,不用去关心请求具体是如何被处理的。
成都创新互联专注于潘集网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供潘集营销型网站建设,潘集网站制作、潘集网页设计、潘集网站官网定制、成都微信小程序服务,打造潘集网络公司原创品牌,更为您提供潘集网站排名全网营销落地服务。
抽象请求处理者(Abstract Request Handler):定义处理请求的接口,包括将请求处理掉和传给下一个对象。
具体请求处理者(Concrete Request Handler):持有下一个处理者对象的引用,具体实现处理请求的接口。
客户端(Client):将请求发送给责任链的头部对象。
某学校的学生请假审批流程:
天数 <= 3:班主任审批通过;
3 < 天数 <= 7:班主任审批不通过,交给年级组长,年级组长审批通过;
7 < 天数 <= 30:年级组长审批不通过,交给教务处,教务处审批通过;
30 < 天数 <= 60:教务处审批不通过,交给校长,校长审批通过;
天数 > 60:校长审批不通过。
不用责任链模式写出的代码:
void handleRequest(int days)
{
if (days <= 3)
{
cout << "班主任审批通过。" << endl;
}
else
{
cout << "班主任审批不通过。交给年级组长。" << endl;
if (days <= 7)
{
cout << "年级组长审批通过。" << endl;
}
else
{
cout << "年级组长审批不通过。交给教务处。" << endl;
if (days <= 30)
{
cout << "教务处审批通过。" << endl;
}
else
{
cout << "教务处审批不通过。交给校长。" << endl;
if (days <= 60)
{
cout << "校长审批通过。" << endl;
}
else
{
cout << "校长审批不通过。" << endl;
}
}
}
}
}
可以看到,这段代码又是一堆if-else又是层层嵌套的,又臭又长,好难看!更重要的问题是,如果流程需要修改,那业务代码也需要修改,不符合开闭原则,难以维护和扩展。
那怎么样提高程序的可扩展性呢?
我们应该把班主任、年级组长等等拆分出来当做请求处理者,并指定一个共同的抽象父类,父类里面定义抽象接口,子类具体实现这些接口。
UML类图:
代码:
#include
using namespace std;
/** 抽象处理者 */
class AbstractRequestHandler
{
protected:
const char *name;
const int maxDaysLimit;
AbstractRequestHandler *const nextHandler; // 由于链条中最后一个处理者没有下一个处理者,但是c++不像java那样存在空引用,所以只能用指针了
AbstractRequestHandler(
const char *name,
const int maxDaysLimit,
AbstractRequestHandler *const nextHandler
) :
name(name),
maxDaysLimit(maxDaysLimit),
nextHandler(nextHandler)
{ }
virtual ~AbstractRequestHandler()
{
if (nextHandler)
{
delete nextHandler;
}
}
virtual void handleRequest(int days)
{
if (days <= maxDaysLimit)
{
cout << name << "审批通过" << endl;
}
else
{
cout << name << "审批不通过";
if (nextHandler)
{
cout << ",转交给" << nextHandler->name << endl;
nextHandler->handleRequest(days);
}
}
}
friend class Client;
};
/** 具体处理者————校长 */
class Principal : public AbstractRequestHandler
{
public:
Principal() : AbstractRequestHandler("校长", 60, nullptr) { }
};
/** 具体处理者————教务处 */
class AcademicAffairsOffice : public AbstractRequestHandler
{
public:
AcademicAffairsOffice() : AbstractRequestHandler("教务处", 30, new Principal) { }
};
// 年级组长、班主任 略
/** 客户端 */
class Client
{
HeadTeacher headTeacher;
public:
Client() : headTeacher() { }
void sendRequest(int days)
{
headTeacher.handleRequest(days);
}
};
int main()
{
Client client;
int days = 10;
cout << "学生将为期" << days << "天的请求交给班主任" << endl;
client.sendRequest(days);
return 0;
}