03.15 設計模式---責任鏈模式(C++實現)

責任鏈模式(Chain of Responsibility Pattern)為請求創建一個接受者對象的鏈。這種模式給與請求的類型,對請求的發送者和接受者進行解耦。屬於行為型模式。

在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。

意圖

避免請求發送者和接受者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條連傳遞請求,直到有對象處理它為止。

主要解決

職責鏈上的處理者負責處理請求,客戶只需要將請求發送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的發送者和請求的處理者解耦了。

如何解決

攔截的類都統一實現接口

優點

1. 降低耦合度,它將請求的發送者和接受者解耦

2. 簡化了對象,使得對象不需要知道鏈的結構

3.增強給對象指派職責的靈活性。通過改變鏈內的成員或者調用他們的次序,允許動態新增或刪除責任

4. 增加新的請求處理很方便

缺點

1. 不能保證請求一定會被接收;

2. 系統性能將受到一定的影響,而且在進行代碼調試時不太方便,可能造成循環調用

3. 可能不容易觀察運行時的 特徵,有礙於出錯

使用場景

1. 有多個對象可以處理同一個請求,具體哪個對象處理請求由運行時刻自動確定。

2. 在不明確指定接受者的 情況下,向多個對象中的一個提交一個請求。

3. 可動態指定一組對象處理請求

UML類圖:

設計模式---責任鏈模式(C++實現)

C++實現

舉個例子:

以後上班的我想要請假這個流程是這樣的:首先我得向項目經理提交休假申請;我的項目經理 向 項目主管提交了我的休假申請,項目主管 向 部門經理提交我的休假申請;最後,部門經理同意了我的休假申請。那麼如果部門經理休假了,這個申請由誰來審批呢?這個時候就會交給項目主管進行審批。是挺麻煩的,但也是公司正常運行的必要。 在處理這個請假審批時,各個人員就好比在一條鏈上的節點,我不知道我的請求由誰審批,但是,我的請求最終會有人來處理的。這就是我想要實現的責任鏈模式。

設計模式---責任鏈模式(C++實現)

解釋: 對於每個角色,他們都有他們的職責;當我提交了休假申請時,項目經理需要判斷,看看自己能否處理,如果休假超過了2個小時,那麼項目經理就不能處理了;項目經理將這個請求提交到項目主管,項目主管判斷部門經理在不在,如果部門經理在,項目主管就不能處理了;最後,我的休假申請就到了部門經理那裡了,由他親自審批。可以很明顯的看到,項目經理、項目主管和部門經理都有可能處理我的休假申請,我的請求沿著這條鏈一直走下去,直到有人處理了我的請求。

code :

[cpp] view plain copy

  1. //責任鏈模式

  2. class HolidayRequest

  3. {

  4. public:

  5. HolidayRequest(int hour)

  6. :m_iHour(hour)

  7. {}

  8. int GetHour()

  9. {

  10. return m_iHour;

  11. }

  12. private:

  13. int m_iHour;

  14. };

  15. class Manager

  16. {

  17. public:

  18. virtualbool HandleRequest(HolidayRequest* request) = 0;

  19. };

  20. class PM : public Manager //PM:Project manager項目經理

  21. {

  22. public:

  23. PM(Manager* handler)

  24. :m_Handler(handler)

  25. {}

  26. bool HandleRequest(HolidayRequest* request)

  27. {

  28. if (request->GetHour() <= 2 || m_Handler == NULL)

  29. {

  30. cout << "PM said : OK" << endl;

  31. returntrue;

  32. }

  33. return m_Handler->HandleRequest(request);

  34. }

  35. private:

  36. Manager* m_Handler;

  37. };

  38. class DM : public Manager //DM:Department Manager部門經理

  39. {

  40. public:

  41. DM(Manager* handler)

  42. :m_handler(handler)

  43. {}

  44. bool HandleRequest(HolidayRequest* request)

  45. {

  46. cout <

  47. returntrue;

  48. }

  49. bool IsIn()

  50. {

  51. returntrue;

  52. }

  53. private:

  54. Manager *m_handler;

  55. };

  56. class PS : public Manager //Project Supervisor部門主管

  57. {

  58. public:

  59. PS(Manager* handler)

  60. :m_handler(handler)

  61. {}

  62. bool HandleRequest(HolidayRequest* request)

  63. {

  64. DM* pDM = dynamic_cast(m_handler);

  65. if (pDM != NULL)

  66. {

  67. if (pDM->IsIn())

  68. return pDM->HandleRequest(request);

  69. }

  70. cout <

  71. returntrue;

  72. }

  73. private:

  74. Manager* m_handler;

  75. };

客戶端:

[cpp] view plain copy

  1. int tets_chain_of_Responsibility_Pattern() //責任鏈模式

  2. {

  3. DM* pDM = new DM(NULL);//部門經理

  4. PS* pPS= new PS(pDM);//部門主管

  5. PM* pPM = new PM(pPS);//項目經理

  6. HolidayRequest* Prequest = new HolidayRequest(10);

  7. pPM->HandleRequest(Prequest);

  8. delete Prequest;

  9. Prequest = new HolidayRequest(2);

  10. pPM->HandleRequest(Prequest);

  11. delete pDM;

  12. delete pPS;

  13. delete pPM;

  14. delete Prequest;

  15. system("pause");

  16. return 0;

  17. }

總結

責任鏈模式的實現時,需要處理好它的後繼者問題,也就是說,如果我不處理這個請求,那麼我將把這個請求發給誰去處理呢?同時,責任鏈模式在實現時,它的鏈的形狀不是職責鏈本身建立和維護的,而是由客戶進行創建的,這就大大提高了責任鏈的靈活性。


分享到:


相關文章: