设计模式(十八)——职责链模式
一、职责链模式简介
1、职责链模式简介
职责链模式(Chain Of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将可能处理请求的对象连成一条链,并沿着这条链传递请求,直到有一个对象处理请求为止。
2、职责连模式角色
Handler类:职责对象抽象类,定义一个处理请求的接口。
ConcreteHandler类:职责对象具体类,实现具体的处理请求的接口。
3、职责链模式优缺点
职责链模式的优点:
A、当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理请求。
B、接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,仅需要保持一个指向其后继者的引用,而不需要保持所有的候选接收者的引用。
C、由于是在客户端来定义链的结构,所以用户可以随时地增加或者修改处理一个请求的结构,增强了给对象指派职责的灵活性。
职责链模式的缺点:
一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。
4、职责链模式使用场景
职责链模式使用场景:
A、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
B、在不明确指定接收者的情况下,向多个对象中的一个提交请求。
C、可处理一个请求的对象集合应被动态指定。
二、职责连模式实现
Handler抽象类:
#ifndef HANDLER_H
#define HANDLER_H
#include <iostream>
using namespace std;
//处理请求的抽象类
class Handler
{
public:
//设置后继处理请求者
void setSuccessor(Handler* successor)
{
m_successor = successor;
}
//处理请求的接口
virtual void handleRequest(int n) = 0;
protected:
Handler(){}
protected:
Handler* m_successor;//后继者
};
#endif // HANDLER_H
ConcreteHandlerA具体处理类:
#ifndef CONCRETEHANDLERA_H
#define CONCRETEHANDLERA_H
#include "Handler.h"
//处理请求的具体实现类
class ConcreteHandlerA : public Handler
{
public:
void handleRequest(int n)
{
if(n < 1000)
{
cout << "ConcreteHandlerA::handleRequest n = " << n << endl;
}
else//如果n>1000,由后继者处理请求
{
if(m_successor)
m_successor->handleRequest(n);
}
}
};
#endif // CONCRETEHANDLERA_H
ConcreteHandlerB具体处理类:
#ifndef CONCRETEHANDLERB_H
#define CONCRETEHANDLERB_H
#include "Handler.h"
//处理请求的具体实现类
class ConcreteHandlerB : public Handler
{
public:
void handleRequest(int n)
{
cout << "ConcreteHandlerB::handleRequest n = " << n << endl;
}
};
#endif // CONCRETEHANDLERB_H
客户调用程序:
#include "Handler.h"
#include "ConcreteHandlerA.h"
#include "ConcreteHandlerB.h"
int main()
{
Handler* a = new ConcreteHandlerA();
Handler* b = new ConcreteHandlerB();
a->setSuccessor(b);
a->handleRequest(200);
a->handleRequest(1200);
delete a,b;
return 0;
}
三、职责链模式实例
公司中对于请假、加薪等请求有不同的处理流程,不同的请求需要由经理、技术总监、总经理处理。但所有的请求必须提交给经理,如果经理没有权限,转给技术总监,技术总监没有权限,转给总经理处理。
Request请求类:
#ifndef REQUEST_H
#define REQUEST_H
#include <string>
using namespace std;
//请求
class Request
{
public:
void setType(string type)
{
m_requestType = type;
}
string getType()
{
return m_requestType;
}
void setContent(string content)
{
m_requestContent = content;
}
string getContent()
{
return m_requestContent;
}
void setNumber(int n)
{
m_number = n;
}
int getNumber()
{
return m_number;
}
private:
string m_requestType;//请求类型
string m_requestContent;//请求内容
int m_number;//数量
};
#endif // REQUEST_H
Manager处理请求的抽象类:
#ifndef MANAGER_H
#define MANAGER_H
#include <string>
#include <iostream>
#include "Request.h"
using namespace std;
//Handler抽象类
class Manager
{
public:
~Manager()
{
if(m_superior != NULL)
delete m_superior;
}
//处理请求接口
virtual void requestApplication(Request* request) = 0;
//设置上级
void setSuperior(Manager* superior)
{
m_superior = superior;
}
protected:
Manager(string name)
{
m_name = name;
m_superior = NULL;
}
protected:
string m_name;//管理者姓名
Manager* m_superior;//管理者的上级
};
#endif // MANAGER_H
CommonManager处理请求的具体类:
#ifndef COMMONMANAGER_H
#define COMMONMANAGER_H
#include "Manager.h"
//Handler具体实现类,处理请求的具体对象,经理
class CommonManager : public Manager
{
public:
CommonManager(string name):Manager(name){}
//请求处理函数
void requestApplication(Request* request)
{
if(request->getType() == "ask for leave" && request->getNumber() <= 2)
{
cout << m_name << ":" << request->getContent() << " number:"
<< request->getNumber() << "day approval" << endl;
}
else
{
if(m_superior != NULL)
m_superior->requestApplication(request);
}
}
};
#endif // COMMONMANAGER_H
Majordomo处理请求的具体类:
#ifndef MAJORDOMO_H
#define MAJORDOMO_H
#include "Manager.h"
//Handler具体实现类,处理请求的具体对象,技术总监
class Majordomo : public Manager
{
public:
Majordomo(string name):Manager(name){}
//处理请求函数
void requestApplication(Request* request)
{
if(request->getType() == "ask for leave" && request->getNumber() <= 5)
{
cout << m_name << ":" << request->getContent() << " number:"
<< request->getNumber() << "day approval" << endl;
}
else
{
if(m_superior != NULL)
m_superior->requestApplication(request);
}
}
};
#endif // MAJORDOMO_H
GeneralManager处理请求的具体类:
#ifndef GENERALMANAGER_H
#define GENERALMANAGER_H
#include "Manager.h"
//Handler具体实现类,处理请求的具体对象,总经理
class GeneralManager : public Manager
{
public:
GeneralManager(string name):Manager(name){}
//处理请求函数
void requestApplication(Request* request)
{
if(request->getType() == "ask for leave")
{
cout << m_name << ":" << request->getContent() << " number:"
<< request->getNumber() << "day approval" << endl;
}
else if(request->getType() == "ask for a raise" && request->getNumber() <= 1000)
{
cout << m_name << ":" << request->getContent() << " number:"
<< request->getNumber() << " approval" << endl;
}
else if(request->getType() == "ask for a raise" && request->getNumber() > 1000)
{
cout << m_name << ":" << request->getContent() << " number:"
<< request->getNumber() << " rejected" << endl;
}
}
};
#endif // GENERALMANAGER_H
客户调用程序:
#include "Manager.h"
#include "CommonManager.h"
#include "Majordomo.h"
#include "GeneralManager.h"
int main()
{
Manager* li = new CommonManager("Li");
Manager* zhang = new Majordomo("zhang");
Manager* wang = new GeneralManager("wang");
li->setSuperior(zhang);//设置CommonManager上级为Majordomo
zhang->setSuperior(wang);//设置Majordomo上级为GeneralManager
Request request1;
request1.setType("ask for leave");//请假
request1.setContent("xiaoming ask for leave");
request1.setNumber(1);
li->requestApplication(&request1);
Request request2;
request2.setType("ask for a raise");//加薪
request2.setContent("xiaohong ask for a raise");
request2.setNumber(1000);
li->requestApplication(&request2);
Request request3;
request3.setType("ask for a raise");//加薪
request3.setContent("xiaozhang ask for a raise");
request3.setNumber(2000);
li->requestApplication(&request3);
Request request4;
request4.setType("ask for leave");//请假
request4.setContent("xiaozhang ask for leave");
request4.setNumber(5);
li->requestApplication(&request4);
delete li,zhang,wang;
return 0;
}
转载于:https://blog.51cto.com/9291927/1970363