本文共 2753 字,大约阅读时间需要 9 分钟。
什么是职责链模式?
在GOF的《设计模式:可复用面向对象软件的基础》一书中对职责链模式是这样说的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,直到有一个对象处理它为止;如下图:
对于每个角色,他们都有他们的职责;当我提交了休假申请时,项目经理需要判断,看看自己能否处理,如果休假超过了2个小时,那么项目经理就不能处理了;项目经理将这个请求提交到项目主管,项目主管判断部门经理在不在,如果部门经理在,项目主管就不能处理了;最后,我的休假申请就到了部门经理那里了,由他亲自审批。可以很明显的看到,项目经理、项目主管和部门经理都有可能处理我的休假申请,我的请求沿着这条链一直走下去,直到有人处理了我的请求。
UML类图
Handler:定义了一个处理请求的接口;其它类如果需要处理相同的请求,可以实现该接口就好了;
ConcreteHandler:处理它所负责的请求,如果可处理该请求,就处理掉这个请求;否则将该请求转发给它的下一个可以处理该请求的对象,所以它必须能访问它的下一个可以处理同样请求的对象; Client:向处理对象提出具体的请求。当客户提交一个请求时,请求沿着一条链传递,直至有一个ConcreteHandler对象负责处理它。
使用场合
代码实现:
#includeusing namespace std;#define SAFE_DELETE(p) if(p){delete p;p=NULL;}//假期请求的类class HolidayRequest{public: HolidayRequest(int hour) :m_iHour(hour) {} int GetHour() { return m_iHour; }private: int m_iHour;};//假期处理请求接口class Manager{public: virtual bool HandleRequest(HolidayRequest *pRequest) = 0;};//项目经理class PM :public Manager{public: PM(Manager* handler):m_pHandler(handler) {} bool HandleRequest(HolidayRequest* pRequest) { if (pRequest->GetHour() <= 2 || m_pHandler == NULL) { cout << "项目经理说ok" << endl; return true; } return m_pHandler->HandleRequest(pRequest); }private: Manager* m_pHandler;};//部门经理class DM :public Manager{public: DM(Manager* handler) :m_pHandler(handler) {} bool HandleRequest(HolidayRequest* pRequest) { cout << "部门经理说Ok了" << endl; return true; } //部门经理说ok了 bool IsIn() { return true; }private: Manager* m_pHandler;};//项目主管class PS :public Manager{public: PS(Manager* handler) :m_pHandler(handler) {} bool HandleRequest(HolidayRequest* pRequest) { DM* pDM = dynamic_cast (m_pHandler); if (pDM != NULL) { if (pDM->IsIn()) { return pDM->HandleRequest(pRequest); } } cout << "项目主管说ok" << endl; return true; } private: Manager* m_pHandler;};int main(int argc, char* argv[]){ DM* pDM = new DM(NULL); PS* pPS = new PS(pDM); PM* pPM = new PM(pPS); //在客户端中定义职责链的顺序,逆着来,注意这里 HolidayRequest* pHolidayRequest = new HolidayRequest(10); pPM->HandleRequest(pHolidayRequest); //输出"部门经理说ok了" SAFE_DELETE(pHolidayRequest); pHolidayRequest = new HolidayRequest(2); pPM->HandleRequest(pHolidayRequest); //输出"项目经理说ok了" SAFE_DELETE(pDM); SAFE_DELETE(pPS); SAFE_DELETE(pPM); SAFE_DELETE(pHolidayRequest);}
优缺点:
总结:
职责链模式在实现时,需要处理好它的后继者的问题,就是说,如果我不处理这个请求,那么我将把这个请求发给谁去处理呢?同时,职责链模式在实现时,它的链的形状并不是由职责链本身建立和维护的,而是由客户进行创建的,由客户指定每一个处理者的后继者是谁。这就大大的提高了职责链的灵活性。在实际中,我们也可以将职责链模式与组合模式相结合,一个构件的父构件可以作为它的后继者。