1. 定义
当你想让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式。
2. 类图
3. Example
作为员工需要请假或者加薪,需要经历:技术leader——部门经历——CTO的流程。
package com.gitlearning.hanldegit.patterns.cor;
import lombok.Setter;
@Setter
public abstract class Handler {
String name;
Handler nextHandler;
abstract void handleRequest(int leaveDays);
public Handler(String name) {
this.name = name;
}
}
class HandlerA extends Handler {
public HandlerA(String name) {
super(name);
}
@Override
void handleRequest(int leaveDays) {
if (leaveDays <= 3) {
System.err.println(String.format("%s批准了你的请假天数: %s天", name, leaveDays));
} else {
nextHandler.handleRequest(leaveDays);
}
}
}
class HandlerB extends Handler {
public HandlerB(String name) {
super(name);
}
@Override
void handleRequest(int leaveDays) {
if (leaveDays <= 7) {
System.err.println(String.format("%s批准了你的请假天数: %s天", name, leaveDays));
} else {
nextHandler.handleRequest(leaveDays);
}
}
}
class HandlerC extends Handler {
public HandlerC(String name) {
super(name);
}
@Override
void handleRequest(int leaveDays) {
System.err.println(String.format("%s批准了你的请假天数: %s天", name, leaveDays));
}
}
class Test {
public static void main(String[] args) {
HandlerA handlerA = new HandlerA("技术leader");
HandlerB handlerB = new HandlerB("部门经理");
HandlerC handlerC = new HandlerC("CTO");
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
handlerA.handleRequest(1);
handlerA.handleRequest(5);
handlerA.handleRequest(8);
}
}
输出结果:
技术leader批准了你的请假天数: 1天
部门经理批准了你的请假天数: 5天
CTO批准了你的请假天数: 8天
由此可见,请求被处理的时候,你不知道是谁在进行处理。请求有可能会被处理,也有可能不会被处理。
4. 使用
- Spring拦截器链、servlet过滤器链等都采用了责任链设计模式。
5.其他
责任链的优点:
-
将请求的发送者和接受者解耦
-
可以简化你的对象,因为它不需要知道链的结构
-
通过改变链内的成员或调动它们的次序,允许动态新增或者删除Handler
缺点:
- 可能不易观察运行时的特征