职责链设计模式
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
为请求创建了一个接收者对象的链(简单示意图)。这种模式对请求的发送者和接收者进行解耦。
职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的 请求传给下一个接收者,依此类推。
这种类型的设计模式属于行为型模式
使用场景
学校 OA 系统的采购审批项目:需求是
职责链模式的注意事项和细节
- 将请求和处理分开,实现解耦,提高系统的灵活性
- 简化了对象,使对象不需要知道链的结构
- 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在 Handler 中设置一个 最大节点数量,在 setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地 破坏系统性能
- 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂
- 最佳应用场景:有多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web 中 Tomcat 对 Encoding 的处理、拦截器
/**
责任链设计模式的思想很简单,就是按照链的顺序执⾏⼀个个处理⽅法,
链上的每⼀个任务都持有它后⾯那个任务的对象引⽤,
以⽅便⾃⼰这段执⾏完成之后,调⽤其后⾯的处理逻辑。
下⾯是⼀个责任链设计模式的简单的实现:
**/
public interface Task {
public void run();
}
public class Task1 implements Task {
private Task task;
public Task1() {
}
public Task1(Task task) {
this.task = task;
}
@Override
public void run() {
System.out.println("task1 is run");
if (task != null) {
task.run();
}
}
}
public class Task2 implements Task {
private Task task;
public Task2() {
}
public Task2(Task task) {
this.task = task;
}
@Override
public void run() {
System.out.println("task2 is run");
System.out.println("task2 is run");
if (task != null) {
task.run();
}
}
}
public class Task3 implements Task {
private Task task;
public Task3() {
}
public Task3(Task task) {
this.task = task;
}
@Override
public void run() {
System.out.println("task3 is run");
if (task != null) {
task.run();
}
}
}
public class LiabilityChain {
public void runChain() {
Task task3 = new Task1();
Task task2 = new Task2(task3);
Task task1 = new Task3(task2);
task1.run();
}
}
public class ChainTest {
public static void main(String[] args) {
LiabilityChain chain = new LiabilityChain();
chain.runChain();
}
}