(六)责任链模式-C++实现
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
责任链模式是使用多个对象处理用户请求的成熟模式,它的关键是将这处理对象组成一个链。每个对象含有后继对象的引用,如果不能处理目前的请求就把它传给后继对象处理。
该模式中有两种角色:
1、处理者:是一个接口或者抽象类,规定了具体处理者处理用户请求的方法,还有设置后继对象的方法
2、具体处理者:是具体的处理者的实现。
本例子中,是一个查询用户身份证号码的例子,不同的具体处理者代表不同的城市,然后对一个身份证号码的请求进行处理。有三个文件,Handler.h和Handler.cpp以及测试用的ResponsibilityChainTest.cpp
(1)Handler.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef _HANDLER_H_ 2 #define _HANDLER_H_ 3 #include <iostream> 4 #include <list> 5 #include <string> 6 using namespace std; 7 8 /* 9 责任链模式 10 有很多的对象可以处理请求, 11 但是用户并不感知是那个对象处理了他的请求。 12 */ 13 14 //抽象类 15 class Handler{ 16 public: 17 virtual void handleRequest(string number) = 0; 18 virtual void setNextHandler(Handler* handler) = 0; 19 }; 20 21 22 //具体处理者1 23 class Beijing : public Handler{ 24 public: 25 Beijing(); 26 void handleRequest(string number) override; 27 void setNextHandler(Handler* handler) override; 28 29 private: 30 Handler *myHandler; 31 list<string> numberList; 32 }; 33 34 //具体处理者2 35 class Shanghai : public Handler{ 36 public: 37 Shanghai(); 38 void handleRequest(string number) override; 39 void setNextHandler(Handler* handler) override; 40 41 private: 42 Handler *myHandler; 43 list<string> numberList; 44 }; 45 46 //具体处理者3 47 class Tianjin : public Handler{ 48 public: 49 Tianjin(); 50 void handleRequest(string number) override; 51 void setNextHandler(Handler* handler) override; 52 53 private: 54 Handler *myHandler; 55 list<string> numberList; 56 }; 57 58 59 60 #endif
(2)Handler.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "Handler.h" 2 3 Beijing::Beijing() 4 { 5 numberList.push_back("11129812340930034"); 6 numberList.push_back("11129812340930035"); 7 numberList.push_back("11129812340930036"); 8 numberList.push_back("11129812340930037"); 9 } 10 11 void Beijing::handleRequest(string number) 12 { 13 list<string>::iterator it; 14 it = find(numberList.begin(), numberList.end(), number); 15 if (it != numberList.end())//存在 16 { 17 cout << "该人在北京居住" << endl; 18 } 19 else{ 20 cout << "该人不在北京居住" << endl; 21 if (NULL != myHandler) 22 { 23 myHandler->handleRequest(number); 24 } 25 } 26 } 27 28 void Beijing::setNextHandler(Handler* handler) 29 { 30 myHandler = handler; 31 } 32 33 Shanghai::Shanghai() 34 { 35 numberList.push_back("10129812340930031"); 36 numberList.push_back("10129812340930032"); 37 numberList.push_back("10129812340930036"); 38 numberList.push_back("10129812340930037"); 39 } 40 41 void Shanghai::handleRequest(string number) 42 { 43 list<string>::iterator it; 44 it = find(numberList.begin(), numberList.end(), number); 45 if (it != numberList.end())//存在 46 { 47 cout << "该人在上海居住" << endl; 48 } 49 else{ 50 cout << "该人不在上海居住" << endl; 51 if (NULL != myHandler) 52 { 53 myHandler->handleRequest(number); 54 } 55 } 56 } 57 58 void Shanghai::setNextHandler(Handler* handler) 59 { 60 myHandler = handler; 61 } 62 63 64 65 Tianjin::Tianjin() 66 { 67 numberList.push_back("10029812340930031"); 68 numberList.push_back("10029812340930032"); 69 numberList.push_back("10029812340930036"); 70 numberList.push_back("10029812340930037"); 71 } 72 73 void Tianjin::handleRequest(string number) 74 { 75 list<string>::iterator it; 76 it = find(numberList.begin(), numberList.end(), number); 77 if (it != numberList.end())//存在 78 { 79 cout << "该人在天津居住" << endl; 80 } 81 else{ 82 cout << "该人不在天津居住" << endl; 83 if (NULL != myHandler) 84 { 85 myHandler->handleRequest(number); 86 } 87 } 88 } 89 90 void Tianjin::setNextHandler(Handler* handler) 91 { 92 myHandler = handler; 93 }
(3)ResponsibilityChainTest.cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "Handler.h" 2 3 int main() 4 { 5 //创建责任链 6 //一般将责任大(最有可能处理用户请求)的对象放在前面 7 Handler *beijing = new Beijing(); 8 Handler *tianjin = new Tianjin(); 9 Handler *shanghai = new Shanghai(); 10 11 beijing->setNextHandler(tianjin); 12 tianjin->setNextHandler(shanghai); 13 14 //用户进行请求 15 //从责任链的第一个对象开始 16 beijing->handleRequest("10129812340930037"); 17 18 return 0; 19 }
责任链的优势:
1、责任链中对象只和自己的后继是耦合关系,和其他对象毫无关联
2、在处理中分配职责时,责任链给程序更多的灵活性(将责任大的对象放在责任链的前面)
3、应用程序可以动态增加或者删除处理者;也可以动态的改变处理者之间的先后顺序
4、使用责任链的用户不必知道处理者的信息。
适合责任链的场景:
1、有很多对象可以处理用户的请求,希望程序在运行时自动确定处理用户请求的那个对象。
2、程序希望动态定制可处理用户请求的对象集合。