责任链模式
客户端将请求发送到一组责任链中,责任链中的多个处理器依次处理,如A处理器先处理,没有处理,则B处理器开始处理,依次类推,处理完成之后交由请求接受者,客户并不知道具体是哪个处理器处理了请求,从而实现了客户端与请求接受者之间的解耦。当你想要让多个对象有机会处理同一个请求的时候,就可以使用责任链模式。
类型:
行为型模式(类与类之间的行为型模式)
责任链模式中的角色:
- 抽象的处理器对象:定义处理器中的处理请求接口方法。
- 具体的处理器对象:每个处理器只处理请求中自己可以处理的部分。
责任链模式的关系图:
责任链模式示例:
本例子以手机组装流水线为例子:
- 主板已经生产好了,现在要开始组装了。
- 组装手机屏幕
- 组装手机电池
- 组装手机外壳
- 手机组装好了
例子中责任链的关系图:
抽象处理器:
/**
* Create by zhaihongwei on 2018/3/29
* 抽象的处理器接口
*/
public interface Handler {
void handleRequest(Request request);
}
具体的处理器:(组装屏幕的处理器、组装电池的处理器、组装外壳处理器)
/**
* Create by zhaihongwei on 2018/3/29
* 组装屏幕的处理器
*/
public class ScreenHandler implements Handler{
// 下一级处理器的引用
private Handler nextHandler;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Request request) {
if (request instanceof ScreenRequest) {
System.out.println(this.getClass()+ ": 组装好了手机屏幕啦!");
} else {
// 如果手机屏幕处理器处理不了交给下一个处理器处理
nextHandler.handleRequest(request);
}
}
}
/**
* Create by zhaihongwei on 2018/3/29
* 组装电池的处理器
*/
public class BatteryHandler implements Handler {
// 下一级处理器的引用
private Handler nextHandler;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Request request) {
if (request instanceof BatteryRequest) {
System.out.println(this.getClass()+ ": 组装好了手机电池啦!");
}else {
// 如果手机电池处理器处理不了交给下一个处理器处理
nextHandler.handleRequest(request);
}
}
}
/**
* Create by zhaihongwei on 2018/3/29
* 组装外壳处理器
*/
public class ShellHandler implements Handler {
// 下一级处理器的引用
private Handler nextHandler;
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(Request request) {
if (request instanceof ShellRequest) {
System.out.println(this.getClass()+ ": 组装好了手机外壳啦!");
}else {
// 如果手机外壳处理器处理不了交给下一个处理器处理
nextHandler.handleRequest(request);
}
}
}
抽象的请求接口:
/**
* Create by zhaihongwei on 2018/3/29
* 抽象的请求对象
*/
public interface Request {
void request();
}
具体的请求:(组装手机屏幕请求、组装手机电池请求、组装手机外壳请求)
/**
* Create by zhaihongwei on 2018/3/29
* 组装手机屏幕请求
*/
public class ScreenRequest implements Request {
public void request() {
System.out.println("需要组装手机屏幕啦!----->>>");
}
}
/**
* Create by zhaihongwei on 2018/3/29
* 组装手机电池请求
*/
public class BatteryRequest implements Request{
@Override
public void request() {
System.out.println("需要组装手机电池啦!----->>>");
}
}
/**
* Create by zhaihongwei on 2018/3/29
* 组装手机外壳请求
*/
public class ShellRequest implements Request{
@Override
public void request() {
System.out.println("需要组装手机外壳啦!----->>>");
}
}
客户端类:本例中相当于测试类:
/**
* Create by zhaihongwei on 2018/3/29
* 客户端类
*/
public class Client {
public static void main(String[] args) {
System.out.println("--------发出请求:手机主板已经生产好了!需要组装屏幕,电池和外壳!---------");
// 创建请求
ScreenRequest screenRequest = new ScreenRequest();
BatteryRequest batteryRequest = new BatteryRequest();
ShellRequest shellRequest = new ShellRequest();
// 创建处理器
ScreenHandler screenHandler = new ScreenHandler();
BatteryHandler batteryHandler = new BatteryHandler();
ShellHandler shellHandler = new ShellHandler();
// 将处理器连接成一条责任链(流水线)
screenHandler.setNextHandler(batteryHandler);
batteryHandler.setNextHandler(shellHandler);
// 发送请求并处理,因为流水线上的工位都是固定的,
// 所有的请求只需要传给责任链中的第一个处理器就可以了,责任链会自行决定由哪个处理器处理请求
screenRequest.request();
screenHandler.handleRequest(screenRequest);
batteryRequest.request();
screenHandler.handleRequest(batteryRequest);
screenRequest.request();
screenHandler.handleRequest(shellRequest);
System.out.println("-------------------------手机已经组装好了!------------------------------");
}
}
测试结果:
--------发出请求:手机主板已经生产好了!需要组装屏幕,电池和外壳!---------
需要组装手机屏幕啦!----->>>
class chain.ScreenHandler: 组装好了手机屏幕啦!
需要组装手机电池啦!----->>>
class chain.BatteryHandler: 组装好了手机电池啦!
需要组装手机屏幕啦!----->>>
class chain.ShellHandler: 组装好了手机外壳啦!
----------------------手机已经组装好了!交给手机接受者!--------------------
----------------------我是手机接受者,接受到了完整的手机--------------------
总结:
通过上面的例子,可以看到,通过使用责任链模式,客户端发出请求之后并不需要知道到底是哪个处理器处理了该请求并将成品交个了手机接收对象,从而实现了客户端对象和接收对象之间的解耦。
责任链模式的纯与不纯
纯的责任链模式:
- 纯的责任链模式要求一个处理器只能在两个行为中选择一个:一是处理请求,二是把请求传递给下级处理器处理。不允许出现某一个处理器在处理了一部分请求后又把请求向下级传递的情况。
- 在纯的责任链模式里面,一个请求必须被某一个处理器处理。
不纯的责任链模式:
- 不纯的责任链模式可以在处理了请求之后,再将请求传递给下级处理器再进行处理。
- 在不纯的责任链模式里面,一个请求可以最终不被任何处理器对象处理。
责任链模式的优缺点:
优点:
- 实现了客户端对象和接受对象之间的解耦。
- 可以动态的增加责任链中的处理器,扩展性比较好。
缺点:
- 效率较低,一个请求可能要走完责任链的中的每一个的环节,就比如手机外壳的请求。