一.职责链模式的简介
职责链模式(Chain of Responsibility Pattern)使多个对象都有机会处理请求,从而避免请求发送者和请求的接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
职责链模式的核心思路: 客户端只需要发送请求,职责链上的处理者负责处理,客户端不用关心请求是如何处理的以及请求是如何依次传递的。可用来实现了对请求的过滤、拦截等操作。
职责链模式应用案例: Struts2中的拦截器的实现,Servlet中的Filter。
二.职责链模式的源码讲解
1.设计类图:
(图片加载慢,多刷新几下,耐心等待……)
注:具体职责处理类(ConcreteHandler)和抽象处理类(Handler),二者是继承关系也是聚合关系。
聚合关系:具体职责处理类(ConcreteHandler)包含抽象处理类(Handler),但抽象处理类(Handler)不是具体职责处理类(ConcreteHandler)的一部分。
三.职责链模式的代码实现
1.职责处理抽象类(Handler)
设计分析: 职责处理抽象类
提供一个处理具体请求方法接口,并且绑定一个职责类对象,作为当不能处理该请求时的交接对象,让下一个职责类尝试处理。
package com.pattern.responsibility;
/**
* 抽象的请求处理类
*
*/
public abstract class Handler {
// 聚合处理类对象
protected Handler handler;
public void setHandler(Handler handler) {
this.handler = handler;
}
// 处理请求
public abstract void handleRequest(int request);
}
2.具体职责处理类(ConcreteHandler)
设计分析 实现处理一个具体的请求,并且当不能处理时,将请求转发给职责链中的下一个职责类对象。
注:这里模拟实现三个具体职责处理类,组成一个职责链,接收处理请求。
第一个具体处理类:
package com.pattern.responsibility;
/**
* 具体处理类1
*
*/
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(int request) {
// 满足条件则处理请求
if (request >= 0 && request < 5) {
System.out.println(request+"该请求被" + this.getClass().getName() + "处理");
} else if (handler != null) {
// 不满足条件,并且下一个处理类不为空,则转到责任链中下一个处理类中
handler.handleRequest(request);
}
}
}
第二个具体处理类:
package com.pattern.responsibility;
/**
* 具体处理类2
*
*/
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(int request) {
// 满足条件则处理请求
if (request >= 5 && request < 10) {
System.out.println(request+"该请求被" + this.getClass().getName() + "处理");
} else if (handler != null) {
// 不满足条件,并且下一个处理类不为空,则转到责任链中下一个处理类中
handler.handleRequest(request);
}
}
}
第三个具体处理类:
package com.pattern.responsibility;
/**
* 具体处理类3
*
*/
public class ConcreteHandler3 extends Handler {
@Override
public void handleRequest(int request) {
// 满足条件则处理请求
if (request >= 10 && request < 15) {
System.out.println(request+"该请求被" + this.getClass().getName() + "处理");
} else if (handler != null) {
// 不满足条件,并且下一个处理类不为空,则转到责任链中下一个处理类中
handler.handleRequest(request);
}
}
}
3.客户端(Client)中用法:
**设计分析:**展示发起请求、命令调用、命令接受、命令执行的实现 。
代码如下:
package com.pattern.responsibility.Client;
import com.pattern.responsibility.ConcreteHandler1;
import com.pattern.responsibility.ConcreteHandler2;
import com.pattern.responsibility.ConcreteHandler3;
import com.pattern.responsibility.Handler;
public class Client {
public static void main(String[] args) {
// 创建责任链中的责任对象
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
// 设置责任链中责任对象的后继者和顺序
handler1.setHandler(handler2);
handler2.setHandler(handler3);
// 模拟一系列的请求
int[] requests = { 1, 3, 5, 7, 9, 11, 13, 15, 20 };
// 依次发送请求,测试责任链处理请求
for (int request : requests) {
handler1.handleRequest(request);
}
}
}
6.运行结果
结果分析: 在请求队列里的15
,20
这两个请求,由于职责链中没有能够处理的职责类,导致这两个请求没有被接收和执行,这也是职责链模式的一个缺点,所以在应用该模式的时候,一定要把“职责类”考虑的全面些,否则会造成请求丢失的问题。
1该请求被com.pattern.responsibility.ConcreteHandler1处理
3该请求被com.pattern.responsibility.ConcreteHandler1处理
5该请求被com.pattern.responsibility.ConcreteHandler2处理
7该请求被com.pattern.responsibility.ConcreteHandler2处理
9该请求被com.pattern.responsibility.ConcreteHandler2处理
11该请求被com.pattern.responsibility.ConcreteHandler3处理
13该请求被com.pattern.responsibility.ConcreteHandler3处理
7.源码下载
本文示例代码下载地址:点击下载
三.总结:
职责链模式为请求创建了一个接受者对象的链,对请求的发送者和接受者进行解耦,每个接受者都会包含对另一个接受者的引用,若不能处理该请求,则传递给下一个接受者,职责链模式属于行为型模式。
1.职责链模式的优点
- 降低了请求者和接受者的耦合度。
- 灵活的新增、调换、删除职责链中的职责类,不影响其他功能的使用。
2.职责链模式的缺点
- 请求不能保证一定被接收到,需要在设计时考虑全面。
- 增加错误排查的复杂度。