責任鏈的目的是通過特定的設計對請求者和接收者之間進行解耦,請求者調用操作的對象,接收者接收請求並執行相關操作,通過解耦請求者不需要關心接收者的介面,同時也可增強職責的靈活性,通過改變鏈內的成員或調用次序,允許動態新增或刪除責任。 作用 責任鏈模式通過將多個對象連成鏈式模式,並沿著這個鏈傳遞命令或者請 ...
責任鏈的目的是通過特定的設計對請求者和接收者之間進行解耦,請求者調用操作的對象,接收者接收請求並執行相關操作,通過解耦請求者不需要關心接收者的介面,同時也可增強職責的靈活性,通過改變鏈內的成員或調用次序,允許動態新增或刪除責任。
作用
責任鏈模式通過將多個對象連成鏈式模式,並沿著這個鏈傳遞命令或者請求,直到有對象處理它為止。
類視圖
實現
我們還是取比較經典的員工請假的例子。員工為請假的請求者,接收者分別從項目經理、部門經理、公司經理這幾個層級,員工向上進行請假操作,首先傳遞給項目經理,項目經理在處理時分為兩種情況,如果項目經理人在公司,並且員工的請假天數滿足請假的審批許可權範圍,則給予審批,反之則申請上級進行處理。
當然我們也可以制定自己的特殊規則,比如經理級別的接收者如果人不在,就不能向上進行請求,比如開可以增加請假的事由以供經理進行判斷是否滿足請假要求等,這些都可以根據實際情況進行擴充,感興趣可以自己實現。
class DayOffRequest
{
public:
DayOffRequest(int hour)
:m_iHour(hour)
{}
int GetHour()
{
return m_iHour;
}
private:
int m_iHour;
};
class Manager
{
public:
virtual bool HandleRequest(DayOffRequest* request) = 0;
};
class PM : public Manager //Project manager項目經理
{
public:
PM(Manager* handler)
:m_Handler(handler)
{}
bool HandleRequest(DayOffRequest* request)
{
//在權責範圍內給予批准
if (request->GetHour() <= 2)
{
cout << "PM said : OK" << endl;
return true;
}
else if (m_Handler) //請求上級
{
return m_Handler->HandleRequest(request);
}
else
{
//無法定奪
cout <<"PM said :no decide" << endl;
return false;
}
}
private:
Manager* m_Handler;
};
class DM : public Manager //Department Manager部門經理
{
public:
DM(Manager* handler)
:m_handler(handler)
{}
bool HandleRequest(DayOffRequest* request)
{
if (m_Handler)
{
if(request->getHour() <=16)
{
cout <<"DM said :OK" << endl;
return true;
}
else
return m_Handler->HandleRequest(request);
}
else
{
cout <<"DM said :no decide" << endl;
return false;
}
}
private:
Manager *m_handler;
};
class GM : public Manager //General Manager 總經理
{
public:
GM():m_handler(NULL) {}
bool IsInCompany()
{
return static_cast<bool>(rand()%2) ;
}
bool HandleRequest(DayOffRequest* request)
{
if(IsInCompany())
{
cout <<"GM said :OK" << endl;
return true;
}
else
{
cout <<"GM said :try again latter" << endl;
return false;
}
}
private:
Manager* m_handler;
};
int main()
{
Manager *general = new GM();
Manager *department = new DM(general); //設置上級
Manager *project = new PM(department); //設置上級
DayOffRequest reqsta(2); //一個員工請假2小時
project->DealWithRequest(&reqsta);
DayOffRequest reqstb(20); //另一個員工請假20小時
project->DealWithRequest(&reqstb);
delete project;
delete department;
delete general;
}
責任鏈和觀察者模式比較相像,都是進行命令和數據的傳遞,二者的關鍵區別是一個是有明確層級和先後關係(也可能不是那麼明顯),而一個是對象平等的,最通俗的例子就是網路中的DNS路由(鏈式)和廣播模式(群發)的實現,這下大家就明白了吧;
當然也請註意鏈式結構的效率問題,對於層級最好還是加以控制。
應用場景
- 基於鏈式的請求和應答的結構;
- 發送者並不知道在鏈中的哪個對象會響應請求;
- 責任鏈中的每一個對象都有職責絕對是否對請求進行響應