职责链模式的原理和实现。主要用于框架中过滤器和拦截器实现
职责链模式,英文名Chain Of Responsibility Design Pattern 。将请求的发送和接收者解耦,让多个接收对象都有机会处理这个请求,将这些接收对象串成一条链。并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它。
进一步解读:
在职责链模式中,多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。一个请求先经过A处理器处理,然后再把请求传递给B处理器,B处理器处理完成之后再传递给C处理器。依次类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责。所以称之为职责链模式。
所以每个接收对象有两种行为:1)、处理请求 2)、传递请求到下一个接收对象
职责链的实现
职责链的实现包含两个部分:1、接收对象的实现 2、职责链处理器类的实现
1、接收对象的实现。包含两部分:抽象接收对象和具体接收对象
抽象接收对象:定义了一个处理请求的接口,供具体接收对象实现
具体接收对象:实现处理请求的接口,该接口需要完成两件事:
a、处理请求
b、如果该接收对象可以处理请求,则终止传递,否则,将请求传递给下一个接收对象
2、职责链处理器类实现
责任链处理器包含一个维护接收对象的集合(可以使用链表,也可以使用数组),一个添加接收对象的方法以及一个依次执行接收对象处理请求的方法。
职责链处理器类使用链表维护接收对象的实现
类图如下
代码实现如下:
/**
* 抽象接收对象
*/
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handle();
}
/**
* 具体接收对象A
*/
public class HandlerA extends Handler{
@Override
public void handle() {
boolean result=false;
System.out.println("对象A处理请求");
if(!result && successor!=null){ //把请求传递给下一个接收对象
successor.handle();
}
}
}
/**
* 具体接收对象B
*/
public class HandlerB extends Handler {
@Override
public void handle() {
boolean result=false;
System.out.println("对象B处理请求");
if(!result && successor!=null){ //把请求传递个下一个对象
successor.handle();
}
}
}
/**
* 职责链处理器
*
* 包含一个维护接收对象的集合(链表),
* 一个添加接收对象的方法以及一个依次执行接收对象处理请求的方法
*/
public class HandlerChain {
private Handler head; //链表的头节点指针
private Handler tail; //链表的尾节点指针
public void addHandler(Handler handler){
handler.setSuccessor(null); //新添加的节点指向下一个节点指针设置为空
if(head==null){ //链表对头节点处理
head=handler;
tail=handler;
return;
}
tail.setSuccessor(handler); //添加节点
tail=handler; //尾节点指针指向新添加的节点
}
public void handle(){
if(head!=null){
head.handle();
}
}
}
测试案例:
@Test
public void test(){
HandlerChain handlerChain=new HandlerChain();
handlerChain.addHandler(new HandlerA());
handlerChain.addHandler(new HandlerB());
handlerChain.handle();
}
执行结果:
实际上,上面的代码还不够完美。其中接收对象中的处理方法headle()包含了自己的业务代码,还包含了把请求传递给下一个接收对象的代码。这部分代码需要重构,使用模板模式,把业务从该方法中剥离。
代码优化如下:
/**
* 抽象接收对象
*/
public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public void handle(){
boolean result=dohandle(); //业务逻辑的处理
if(!result && successor!=null){ //把请求传递给下一个参数
successor.handle();
}
}
public abstract boolean dohandle();
}
/**
* 具体接收对象A
*/
public class HandlerA extends Handler{
@Override
public boolean dohandle() {
boolean result=false;
System.out.println("对象A处理请求");
return result;
}
}
/**
* 具体接收对象B
*/
public class HandlerB extends Handler {
@Override
public boolean dohandle() {
boolean result=false;
System.out.println("对象B处理请求");
return result;
}
}
职责链处理器类使用数组维护接收对象的实现
使用数组相对来说要简单一点,代码如下
/**
* 抽象接收对象
*/
public interface Ihandler {
public boolean handle();
}
/**
* 接收对象C
*/
public class HandlerC implements Ihandler{
@Override
public boolean handle() {
boolean result=false;
//..业务逻辑代码省略
return result;
}
}
/**
* 接收对象D
*/
public class HandlerD implements Ihandler{
@Override
public boolean handle() {
boolean result=false;
//..业务逻辑代码省略
return result;
}
}
/**
* 职责链处理器类
*/
public class HandlerChainOfArray {
private List<Ihandler> handlers=new ArrayList<>();
public void addHandler(Ihandler handler){
handlers.add(handler);
}
public void handle(){
for(Ihandler handler:handlers){
boolean result = handler.handle();
if(result){
break;
}
}
}
}
上面是标准的职责链处理模式,还有以一种变体,职责链链上的处理器顺序执行,不会终止
总结:
标准职责链:职责链上的处理器按顺序执行,有一个处理器可以处理请求,就终止传递
变体职责链:职责链链上的处理器顺序执行,不会终止。
职责链的实现方式:链表实现和数组实现
参考:设计模式之美 -- 王争