定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成
一条链,并沿着这条链传递请求,直到有一个对象处理它为止。 ——《设计模式》GoF
背景
请假流程,1天内需要主程序批准,3天内需要项目经理批准,3天以上需要老板批准;
代码chain_of_resp1
#include <string> class Context { public: std::string name; int day; }; class LeaveRequest { public: // 随着判断的增加,LeaveRequest类变得不稳定 bool HandleRequest(const Context &ctx) { if (ctx.day <= 3) HandleByMainProgram(ctx); else if (ctx.day <= 10) HandleByProjMgr(ctx); else HandleByBoss(ctx); } private: bool HandleByMainProgram(const Context &ctx) { } bool HandleByProjMgr(const Context &ctx) { } bool HandleByBoss(const Context &ctx) { } };
代码chain_of_resp2
#include <string> class Context { public: std::string name; int day; }; class IHandler { public: virtual ~IHandler() {} void SetNextHandler(IHandler *next) { next = next; } bool Handle(ctx) {//具体的流程还有条件也可以抽象 if (CanHandle(ctx)) { return HandleRequest(); } else if (GetNextHandler()) { return GetNextHandler()->HandleRequest(ctx); } else { // err } } protected: virtual bool HandleRequest(const Context &ctx) = 0; virtual bool CanHandle(const Context &ctx) =0; IHandler * GetNextHandler() { return next; } private: IHandler *next; }; class HandleByMainProgram : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // } virtual bool CanHandle() { // } }; class HandleByProjMgr : public IHandler { protected: virtual bool HandleRequest(const Context &ctx){ // } virtual bool CanHandle() { // } }; class HandleByBoss : public IHandler { public: virtual bool HandleRequest(const Context &ctx){ // } protected: virtual bool CanHandle() { // } }; int main () { IHandler * h1 = new MainProgram(); IHandler * h2 = new HandleByProjMgr(); IHandler * h3 = new HandleByBoss(); h1->SetNextHandler(h2); Context ctx; h1->handle(ctx); return 0; }
要点
- 解耦请求方和处理方,请求方不知道请求是如何被处理,处理方的组成是由相互独立的子处理
构成,子处理流程通过链表的方式连接,子处理请求可以按任意顺序组合; - 责任链请求强调请求最终由一个子处理流程处理;通过了各个子处理条件判断;
- 责任链扩展就是功能链,功能链强调的是,一个请求依次经由功能链中的子处理流程处理;
- 充分体现了单一职责原则;将职责以及职责顺序运行进行抽象,那么职责变化可以任意扩展,
同时职责顺序也可以任意扩展; - 责任链与模板模式加策略模式
- 子类相同挪到父类
本质
- 分离职责,动态组合;
结构图