责任链模式就是将一系列处理请求的对象连起来,每个请求处理对象都有自己的处理权限,此时事件处理对象形成的链状关系就可称为责任链,责任链上每一个事件处理对象都是按事件处理权限顺序依次连接,没有权限处理该事件则将其传递给下一级有权限处理的对象进行事件处理操作,就这样沿着责任链顺序将需处理的事件请求传递直至事件请求被处理为止,适用于不同请求需不同权限对象进行处理的情况,就好比工作中不同的请假天数需要不同权限的领导进行审批操作。
下面是责任链模式的UML图:
现在就以公司审批处理的流程为例实现一个简单的责任链模式,责任链中包含了上级领导、经理、老板这三个审批处理者,默认审批处理的流程为上级 --> 经理 --> 老板,只要任意一级能成功处理审批则完成审批流程,中间若有处理者无法处理则将审批请求自动传递给下一级处理者进行审批处理,直至审批被成功处理为止(实际操作过程中也可以很方便的进行责任链对象的增加或删除,只需增加或删除处理对象并改变m_pNextHandler指针指向即可,这里没有进行相应环节测试,大家可自行测试以验证自己对该模式是否理解),下面就是具体是实现代码及测试结果:
1. 抽象请求处理者定义
class Handler
{
public:
//处理者初始化
Handler(int perms = 1)
{
m_enable = true;
setPermission(perms);
m_pNextHandler = nullptr;
}
//设置下一个处理者对象
void setNextHandler(Handler *handler)
{
m_pNextHandler = handler;
}
//设置当前处理者权限值
void setPermission(int perms = 1)
{
m_permission = perms;
}
//获取当前处理者权限值
int permission() const
{
return m_permission;
}
//设置处理者工作状态
void setEnable(bool enable)
{
m_enable = enable;
}
//请求处理接口
virtual void requestHandle(int req) = 0;
protected:
Handler *m_pNextHandler; //指向下一个请求处理者的指针
bool m_enable; //标识处理者状态,true表示正常工作状态, false表示无法正常工作
int m_permission; //保存处理者的权限值
bool canHandleRequest(int req) //用于判断请求处理者当前是否可处理请求
{
if((req <= permission()) && m_enable) //仅当处理者处于工作状态且满足处理权限才可处理请求
{
return true;
}
return false;
}
};
2. 具体请求处理者:上级
class Superior : public Handler
{
public:
virtual void requestHandle(int req)
{
//能处理请求则直接处理,否则将请求传递给下一个请求处理者处理
if(true == canHandleRequest(req))
{
//处理当前请求
cout << "Superior Handle request " << req << endl;
}
else
{
//传递当前请求给下一个处理者处理
m_pNextHandler->requestHandle(req);
}
}
};
3. 具体请求处理者:经理 (具体操作同上)
class Manager : public Handler
{
public:
virtual void requestHandle(int req)
{
if(true == canHandleRequest(req))
{
cout << "Manager Handle request " << req << endl;
}
else
{
m_pNextHandler->requestHandle(req);
}
}
};
4. 具体请求处理者:老板 (具体操作同上)
class Boss : public Handler
{
public:
virtual void requestHandle(int req)
{
if(true == canHandleRequest(req))
{
cout << "Boss Handle request " << req << endl;
}
else
{
m_pNextHandler->requestHandle(req);
}
}
};
5. 主函数功能测试代码
int main()
{
Superior superior;
superior.setPermission(3);
Manager manager;
manager.setPermission(7);
Boss boss;
boss.setPermission(999999);
superior.setNextHandler(&manager);
manager.setNextHandler(&boss);
superior.requestHandle(3);
superior.requestHandle(5);
superior.requestHandle(8);
manager.setEnable(false);
superior.requestHandle(5);
return 0;
}
程序运行结果:
通过上面的例子可以了解责任链模式的优点一是降低了请求发送者与接收者的耦合关系(因为每一个处理对象都有机会处理请求,如一个请求处理对象无法处理时,请求就可以传递给其他处理对象处理);二是简化了请求处理对象(请求只需与直接与责任链第一个处理对象关联就行,后续的责任链对象都无需知晓);还有就是责任链可方便的增加或删除处理对象而不需要修改原对象代码。
责任链模式的缺点就是在形成责任链时若流程不清有可能构成死循环,另外就是链式结构只能从前往后依次遍历会使性能降低。