职责链模式
职责链模式定义
职责链模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到一个对象处理它为止。
职责链模式结构图
职责链模式结构图如下所示:
图 01 职责链模式结构图
职责链模式套用代码
1 #include "iostream" 2 using namespace std; 3 4 // 定义一个处理请求的接口 5 class Handler 6 { 7 protected: 8 Handler* successor; 9 public: 10 // 设置继任者 11 void SetSuccessor(Handler* successor) 12 { 13 this->successor = successor; 14 } 15 16 // 处理请求的纯虚函数 17 virtual void HandleRequest(int request) = 0; 18 }; 19 20 // 处理request在0-10之间 21 class ConcreteHandler1 : public Handler 22 { 23 public: 24 virtual void HandleRequest(int request) 25 { 26 if(request >= 0 && request < 10) 27 { 28 cout << "ConcreteHandler1处理请求request = " << request << endl; 29 } 30 else if(successor != NULL) 31 { 32 successor->HandleRequest(request); 33 } 34 } 35 }; 36 37 // 处理request在10-20之间 38 class ConcreteHandler2 : public Handler 39 { 40 public: 41 virtual void HandleRequest(int request) 42 { 43 if(request >= 10 && request < 20) 44 { 45 cout << "ConcreteHandler2处理请求request = " << request << endl; 46 } 47 else if(successor != NULL) 48 { 49 successor->HandleRequest(request); 50 } 51 } 52 }; 53 54 // 处理request在20-30之间 55 class ConcreteHandler3 : public Handler 56 { 57 public: 58 virtual void HandleRequest(int request) 59 { 60 if(request >= 20 && request < 30) 61 { 62 cout << "ConcreteHandler3处理请求request = " << request << endl; 63 } 64 else if(successor != NULL) 65 { 66 // 由于这里是请求处理的末端所以这里必须要非常小心的处理, 67 // 要不然会导致死循环的 68 //successor->HandlerRequest(request); 69 cout << "到达请求末端" << endl; 70 } 71 } 72 }; 73 74 void main() 75 { 76 Handler* h1 = new ConcreteHandler1(); 77 Handler* h2 = new ConcreteHandler2(); 78 Handler* h3 = new ConcreteHandler3(); 79 h1->SetSuccessor(h2); 80 h2->SetSuccessor(h3); 81 82 int a[6] = {2, 5, 14, 22, 18, 33}; 83 for(int i = 0; i < 6; i++) 84 { 85 h1->HandleRequest(a[i]); 86 } 87 88 delete h1; 89 h1 = NULL; 90 91 delete h2; 92 h3 = NULL; 93 94 delete h3; 95 h3 = NULL; 96 }
职责链模式特点
① 当客户提交一个请求时,请求是沿链传递直到一个ConcreteHandler对象负责处理它,这样第个请求都一定会有对象进行处理
② 接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的想到连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用,这样大大降低了耦合度
③ 随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性
④ 需要注意的是:一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这就很糟糕了,需要事先考虑全面
职责链模式实例应用
职责链模式实例应用类图
图 02 职责链模式实例应用类图
职责链模式实例应用代码
1 #include "iostream" 2 using namespace std; 3 #include <string> 4 5 // 请求的内容 6 class Request 7 { 8 private: 9 string requestType; 10 int number; 11 public: 12 string GetRequestType() 13 { 14 return this->requestType; 15 } 16 17 void SetRequestType(string requestType) 18 { 19 this->requestType = requestType; 20 } 21 22 int GetNumber() 23 { 24 return this->number; 25 } 26 27 void SetNumber(int number) 28 { 29 this->number =number; 30 } 31 }; 32 33 // 处理的接口(经理类) 34 class Manager 35 { 36 protected: 37 string name; 38 Manager* superior; 39 public: 40 Manager(string name) 41 { 42 this->name = name; 43 } 44 45 void SetSuperior(Manager* superior) 46 { 47 this->superior = superior; 48 } 49 50 virtual void RequestApplications(Request* request) = 0; 51 }; 52 53 // 普通的经理类 54 class CommonManager : public Manager 55 { 56 public: 57 CommonManager(string name) 58 : Manager(name) 59 { 60 61 } 62 63 virtual void RequestApplications(Request* request) 64 { 65 if(request->GetRequestType() == "请假" && request->GetNumber() <= 2) 66 { 67 cout << " 姓名 = " << name << " 请求类型 = " << request->GetRequestType(); 68 cout << " 数量 = " << request->GetNumber() << " 批准" << endl; 69 } 70 else 71 { 72 if(superior != NULL) 73 { 74 superior->RequestApplications(request); 75 } 76 } 77 } 78 }; 79 80 // 总监 81 class Majordomo : public Manager 82 { 83 public: 84 Majordomo(string name) 85 : Manager(name) 86 { 87 88 } 89 90 virtual void RequestApplications(Request* request) 91 { 92 if(request->GetRequestType() == "请假" && request->GetNumber() <= 5) 93 { 94 cout << " 姓名 = " << name << " 请求类型 = " << request->GetRequestType(); 95 cout << " 数量 = " << request->GetNumber() << " 批准" << endl; 96 } 97 else 98 { 99 if(superior != NULL) 100 { 101 superior->RequestApplications(request); 102 } 103 } 104 } 105 }; 106 107 // 总经理 108 class GeneralManager : public Manager 109 { 110 public: 111 GeneralManager(string name) 112 : Manager(name) 113 { 114 115 } 116 117 virtual void RequestApplications(Request* request) 118 { 119 if(request->GetRequestType() == "请假") 120 { 121 cout << " 姓名 = " << name << " 请求类型 = " << request->GetRequestType(); 122 cout << " 数量 = " << request->GetNumber() << " 批准" << endl; 123 } 124 else if(request->GetRequestType() == "加薪" && request->GetNumber() <= 500) 125 { 126 if(superior != NULL) 127 { 128 cout << " 姓名 = " << name << " 请求类型 = " << request->GetRequestType(); 129 cout << " 数量 = " << request->GetNumber() << " 批准" << endl; 130 } 131 } 132 else if(request->GetRequestType() == "加薪" && request->GetNumber() > 500) 133 { 134 cout << " 姓名 = " << name << " 请求类型 = " << request->GetRequestType(); 135 cout << " 数量 = " << request->GetNumber() << " 加薪太高了,再讲吧" << endl; 136 } 137 } 138 }; 139 140 141 void main() 142 { 143 CommonManager* jinli = new CommonManager("金利"); 144 Majordomo* zongjian = new Majordomo("总监"); 145 GeneralManager* zhongjingli = new GeneralManager("总经理"); 146 jinli->SetSuperior(zongjian); 147 zongjian->SetSuperior(zhongjingli); 148 149 Request* request1 = new Request(); 150 request1->SetRequestType("请假"); 151 request1->SetNumber(1); 152 jinli->RequestApplications(request1); 153 154 Request* request2 = new Request(); 155 request2->SetRequestType("请假"); 156 request2->SetNumber(4); 157 jinli->RequestApplications(request2); 158 159 Request* request3 = new Request(); 160 request3->SetRequestType("加薪"); 161 request3->SetNumber(400); 162 jinli->RequestApplications(request3); 163 164 Request* request4 = new Request(); 165 request4->SetRequestType("加薪"); 166 request4->SetNumber(1000); 167 jinli->RequestApplications(request4); 168 169 delete jinli; 170 jinli = NULL; 171 delete zongjian; 172 zongjian = NULL; 173 delete zhongjingli; 174 zhongjingli = NULL; 175 176 delete request1; 177 request1 = NULL; 178 delete request2; 179 request2 = NULL; 180 delete request3; 181 request3 = NULL; 182 delete request4; 183 request4 = NULL; 184 }
2014-12-07 16:58:38