一,概述
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为之。
优点:客户提出请求时,请求时沿链传递直至有一个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;
}