责任链模式属于行为模式
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
责任链模式关键点是如何将多个处理节点连成一条链。该模式使一个对象无需知道是其他哪一个对象处理其请求,仅需要知道请求处理的结果。
处理者handler处理它所负责的请求,如果可处理则处理,否则将该请求转发给它的后继者
稳定点 多个节点的链式处理流程。
变化点 节点的处理的条件或者处理顺序。
扩展点 动态增删处理节点、调整处理顺序
适用点 一个请求被多个对象处理,并且集合对象应被动态指定。
应用:nginx-处理http流程的11个状态。
员工请假流程
1 先向部门主管申请,主管进行处理。
2 部门主管无权限处理时再向他的上级申请比如项目主管,项目主管进行处理。
3 项目主管无权限处理时再向他的上级申请比如区域主管,区域主管进行处理。
4 ...申请依次向下传递,像链条一样,直到有管理者有权限处理为止。
代码实现
leave.cpp
引入模式后实现
leave_ex.cpp
测试
结论:
1 将请假流程作为一个链表,每个处理者作为处理节点。
2 从单节点出发,实现处理功能以及链表关系,完成传递功能。
3 从实现上看引入模式后代码量增大不少,但是设定了一个稳定点,后续不管是修改每个处理的条件、处理的顺序、以及增删处理都会比较简单,也更加符合设计原则。而原始代码修改这些需要不停的调整以及增删if else判断。
代码示例
leave.cpp
#include
struct Context{int day;
};class LeaveApply{
public:bool Apply(const Context& ctx){if(!DepartmentManagerProcess(ctx)){if(!ProjectManagerProcess(ctx)){if(!RegionalManagerProcess(ctx)){return false;}}}return true;}private:bool DepartmentManagerProcess(const Context& ctx){if(ctx.day < 3){std::cout << "DepartmentManager agree" << std::endl; return true;}return false;}bool ProjectManagerProcess(const Context& ctx){if(ctx.day < 10){std::cout << "ProjectManager agree" << std::endl; return true;}return false;}bool RegionalManagerProcess(const Context& ctx){if(ctx.day < 30){std::cout << "RegionalManager agree" << std::endl; return true;}return false;}
};int main(int arc,char** arg){std::cout << "leave--" << std::endl;Context ctx;ctx.day = 15;if(arc == 2){ctx.day = std::stoi(arg[1]);}LeaveApply la;if(la.Apply(ctx)){std::cout << ctx.day << " days off success" << std::endl;}else{std::cout << ctx.day << " days off failed" << std::endl;}return 0;
}
leave_ex.cpp
#include
struct Context{int day;
};class Manager{
public:virtual bool Process(const Context& ctx) = 0;Manager* get_next(){return next_;}void set_next(Manager* manager){next_ = manager;}private:Manager* next_ = nullptr;
};class DepartmentManager : public Manager{
public: virtual bool Process(const Context& ctx){if(ctx.day < 3){std::cout << "DepartmentManager agree" << std::endl; return true;}return false;}
};class ProjectManager : public Manager{
public: virtual bool Process(const Context& ctx){if(ctx.day < 10){std::cout << "ProjectManager agree" << std::endl;return true;}return false;}
};class RegionalManager : public Manager{
public: virtual bool Process(const Context& ctx){if(ctx.day < 30){std::cout << "RegionalManager agree" << std::endl;return true;}return false;}
};class LeaveApply{
public:LeaveApply(){ManageResponsibility();}~LeaveApply(){while(manager_){auto ptr = manager_;manager_ = manager_->get_next();delete ptr;ptr = nullptr;}}bool Apply(const Context& ctx){if(!manager_){return false;}Manager* cur = manager_;while(cur){if(cur->Process(ctx)){return true; }else{cur = cur->get_next();}}return false;}private:void ManageResponsibility(){Manager* dm = new DepartmentManager();Manager* pm = new ProjectManager();Manager* rm = new RegionalManager();dm->set_next(pm);pm->set_next(rm);manager_ = dm;}Manager* manager_ = nullptr;
};int main(int arc,char** arg){std::cout << "leave2--" << std::endl;Context ctx;ctx.day = 15;if(arc == 2){ctx.day = std::stoi(arg[1]);}LeaveApply la;if(la.Apply(ctx)){std::cout << ctx.day << " days off success" << std::endl;}else{std::cout << ctx.day << " days off failed" << std::endl;}return 0;
};