【设计模式】加薪非要老总批 --- 职责链模式
一,概述
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为之。
优点:客户提出请求时,请求时沿链传递直至有一个ConcreteHandler对象负责处理它
二,职责链基本代码
#include <iostream> using namespace std; class Handler { protected: static Handler *successor; public: void SetSuccessor(Handler *successor) { this->successor = successor; } virtual void HandleRequest(int request) { } }; Handler* Handler::successor=NULL; //必须是static 变量才能在全局初始化 class ConcreteHandler1 :public Handler { public: void HandleRequest(int request) { if (request >= 0 && request < 10) { cout<<"ConcreteHandler1"<<"处理请求"<<request<<endl; } else if (successor != NULL) { successor->HandleRequest(request); } } }; class ConcreteHandler2 :public Handler { public: void HandleRequest(int request) { if (request >= 10 && request < 20) { cout<<"ConcreteHandler2"<<"处理请求"<<request<<endl; } else if (successor != NULL) { successor->HandleRequest(request); } } }; class ConcreteHandler3 :public Handler { public: void HandleRequest(int request) { if (request >= 20 && request < 30) { cout<<"ConcreteHandler3"<<"处理请求"<<request<<endl; } else if (successor != NULL) { successor->HandleRequest(request); } } }; int main() { Handler *h1 = new ConcreteHandler1(); Handler *h2 = new ConcreteHandler2(); Handler *h3 = new ConcreteHandler3(); h1->SetSuccessor(h2);//设置下一个 h2->SetSuccessor(h3);//设置下一个 int request[] = { 2, 5, 14, 22, 18, 3, 27, 20 }; for(int i=0;i<8;++i) { h1->HandleRequest(request[i]); } return 0; }
三,示例
小菜要求加薪,而加薪的批准需要总经理来批准。经理交给总监,总监交给总经理。
缺点:Manager 类 太长,分支太多。如果要增加项目经理、部门经理等职位的话,需要更改原类,比较麻烦。
#include <iostream> using namespace std; //enum ManagerLevel{ "经理","总监","总经理"} ManagerLevel; enum ManagerLevel{ manager,chief_inspector,president} ; //申请 class Request { //申请类别 private: string requestType; public: string getRequestType() { return requestType; } void setRequestType(string value) { requestType = value; } //申请内容 private: string requestContent; public: string getRequestContent() { return requestContent; } void setRequestContent(string value) { requestContent = value; } //数量 private: int number; public: int getNumber() { return number; } void setNumber(int value) { this->number = value; } }; //管理者 class Manager { protected: string name; public: Manager(string name) { this->name = name; } //得到结果 void GetResult(ManagerLevel managerLevel, Request request) { if (managerLevel == manager) { if (request.getRequestType() == "请假" && request.getNumber() <= 2) { //Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number); cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; } else { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"我无权处理"<<endl; //Console.WriteLine("{0}:{1} 数量{2} 我无权处理", name, request.RequestContent, request.Number); } } else if (managerLevel ==chief_inspector) { if (request.getRequestType() == "请假" && request.getNumber() <= 5) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; //Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number); } else { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"我无权处理"<<endl; //Console.WriteLine("{0}:{1} 数量{2} 我无权处理", name, request.RequestContent, request.Number); } } else if (managerLevel == president) { if (request.getRequestType() == "请假") { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; //Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number); } else if (request.getRequestType() == "加薪" && request.getNumber() <= 500) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; // Console.WriteLine("{0}:{1} 数量{2} 被批准", name, request.RequestContent, request.Number); } else if (request.getRequestType() == "加薪" && request.getNumber() > 500) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; // Console.WriteLine("{0}:{1} 数量{2} 再说吧", name, request.RequestContent, request.Number); } } } }; int main() { Manager *jinli = new Manager("金利"); Manager *zongjian = new Manager("宗剑"); Manager *zhongjingli = new Manager("钟精励"); Request *request = new Request(); request->setRequestType("加薪"); request->setRequestContent("小菜请求加薪"); request->setNumber(1000); jinli->GetResult(manager, *request); zongjian->GetResult(chief_inspector, *request); zhongjingli->GetResult(president, *request); Request *request2 = new Request(); request2->setRequestType("请假"); request2->setRequestContent("小菜请假"); request2->setNumber(3); jinli->GetResult(manager, *request2); zongjian->GetResult(chief_inspector, *request2); zhongjingli->GetResult(president, *request2); return 0; }
2)改进后的代码
说明:C++中不可以直接声明类的对象,但是可以直接声明类的指针。
#include <iostream> using namespace std; //enum ManagerLevel{ "经理","总监","总经理"} ManagerLevel; enum ManagerLevel{ manager,chief_inspector,president} ; //申请 class Request { //申请类别 private: string requestType; public: string getRequestType() { return requestType; } void setRequestType(string value) { requestType = value; } //申请内容 private: string requestContent; public: string getRequestContent() { return requestContent; } void setRequestContent(string value) { requestContent = value; } //数量 private: int number; public: int getNumber() { return number; } void setNumber(int value) { this->number = value; } }; //管理者 class Manager { protected: string name; //管理者的上级 Manager *superior; public: Manager(string name) { this->name = name; } //设置管理者的上级 void SetSuperior(Manager *superior) { this->superior = superior; } //申请请求 virtual void RequestApplications(Request request) { } }; //经理 class CommonManager :public Manager { public: CommonManager(string name) : Manager(name) { } void RequestApplications(Request request) { if (request.getRequestType() == "请假" && request.getNumber() <= 2) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; } else { if (superior != NULL) superior->RequestApplications(request); } } }; //总监 class Majordomo :public Manager { public: Majordomo(string name) : Manager(name) { } void RequestApplications(Request request) { if (request.getRequestType() == "请假" && request.getNumber() <= 5) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; } else { if (superior != NULL) superior->RequestApplications(request); } } }; //总经理 class GeneralManager :public Manager { public: GeneralManager(string name): Manager(name) { } void RequestApplications(Request request) { if (request.getRequestType() == "请假") { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; } else if (request.getRequestType() == "加薪" && request.getNumber() <= 500) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"被批准"<<endl; } else if (request.getRequestType() == "加薪" && request.getNumber() > 500) { cout<<name<< request.getRequestContent()<<"数量"<< request.getNumber()<<"再说吧"<<endl; } } }; int main() { CommonManager *jinli = new CommonManager("金利"); Majordomo *zongjian = new Majordomo("宗剑"); GeneralManager *zhongjingli = new GeneralManager("钟精励"); jinli->SetSuperior(zongjian); zongjian->SetSuperior(zhongjingli); Request *request = new Request(); request->setRequestType("请假"); request->setRequestContent("小菜请假"); request->setNumber(1); jinli->RequestApplications(*request); Request *request2 = new Request(); request2->setRequestType("请假"); request2->setRequestContent("小菜请假"); request2->setNumber(4); jinli->RequestApplications(*request2); Request *request3 = new Request(); request3->setRequestType("加薪"); request3->setRequestContent("小菜请求加薪"); request3->setNumber(500); jinli->RequestApplications(*request3); Request *request4 = new Request(); request4->setRequestType("加薪"); request4->setRequestContent("小菜请求加薪"); request4->setNumber(1000); jinli->RequestApplications(*request4); return 0; }