定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
通用类图
具体实现
责任链模式的目的是为了让发送者和接收者解耦,发送者不需要知道请求是由哪个接收者处理,只需要把请求给到由多个对象组成的处理链的头节点,抽象处理类 Handler 会判断是否是本节点要处理的请求,是的话处理请求,不是的话把请求传递给下一个处理者。
抽象处理者:Handler
package com.yrs.chainOfResponsibility;
/**
* @Author: yangrusheng
* @Description: 抽象处理者。主要作用请求接收、传递。
* @Date: Created in 17:04 2020/1/11
* @Modified By:
*/
public abstract class Handler {
/**
* 下一个责任链节点
*/
private Handler nextHandler;
public final void handleRequest(Request request) {
if (request.getLevel() == this.getLevel()) {
//此节点处理
this.doHandle(request);
} else {
//判断是否有下个处理节点,传递请求
if (nextHandler != null) {
this.nextHandler.handleRequest(request);
} else {
System.out.println("this request not handler handle!");
}
}
}
/**
* 设置下个处理节点
* @param nextHandler
*/
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
/**
* 获得处理者能够处理的请求的等级
* @return
*/
protected abstract int getLevel();
/**
* 处理请求
*/
protected abstract void doHandle(Request request);
}
具体处理者:ConcreteHandler
package com.yrs.chainOfResponsibility;
/**
* @Author: yangrusheng
* @Description: 具体处理者
* @Date: Created in 17:26 2020/1/11
* @Modified By:
*/
public class ConcreteHandler1 extends Handler {
@Override
protected int getLevel() {
return 1;
}
@Override
protected void doHandle(Request request) {
System.out.println("concreteHandler1 handle request: " + request.getMsg());
}
}
package com.yrs.chainOfResponsibility;
/**
* @Author: yangrusheng
* @Description: 具体处理者
* @Date: Created in 17:26 2020/1/11
* @Modified By:
*/
public class ConcreteHandler2 extends Handler {
@Override
protected int getLevel() {
return 2;
}
@Override
protected void doHandle(Request request) {
System.out.println("concreteHandler2 handle request: " + request.getMsg());
}
}
请求类:Request
package com.yrs.chainOfResponsibility;
/**
* @Author: yangrusheng
* @Description: 请求类
* @Date: Created in 17:07 2020/1/11
* @Modified By:
*/
public class Request {
/**
* 处理级别
*/
private int level;
/**
* 处理内容
*/
private String msg;
public Request() {
}
public Request(int level, String msg) {
this.level = level;
this.msg = msg;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
场景类:Client
package com.yrs.chainOfResponsibility;
/**
* @Author: yangrusheng
* @Description:
* @Date: Created in 17:04 2020/1/11
* @Modified By:
*/
public class Client {
public static void main(String[] args) {
Request request1 = new Request(1, "request1");
Request request2 = new Request(2, "request2");
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
//设置下一个处理节点
handler1.setNextHandler(handler2);
//提交请求
handler1.handleRequest(request1);
handler1.handleRequest(request2);
}
}
优缺点
责任链模式的优点:
- 将请求的发送者和接受者解耦。
- 可以简化对象,因为它不需要知道链的结构。
- 通过改变链内的成员或调动他们的次序,允许动态地新增或者删除责任。
责任链模式的缺点:
- 性能问题。每个请求都要从链头开始遍历,在链比较长的时候,性能将会是一个问题。
- 调试不方便,不容易定位问题。
使用场景
父类实现了请求传递的功能,子类实现请求的处理,符合单一职责原则。请求到底是谁处理的,请求者不用关心,只需把请求抛给责任链的第一个处理着,最终会返回一个处理结果(也可以不处理),这是责任链模式的核心。
当不同类型的事件,需要不同的处理方式就可以使用责任链模式,但是要注意控制链中节点数量,避免出现超长链的情况,这样会影响程序性能
参考
- 《设计模式之禅-第2版》
- 《Head First 设计模式》