一、责任链模式
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
可以看到责任链模式只有两个角色
-
Handler
所有处理器类的接口 -
ConcreteHandler x
具体的处理器类,其实现Handler接口,有多少个处理器,就定义多少个这样的类
二、责任链模式的实现方式
1、基于链表
链表的实现方式比较复杂。如图:
将传入的第一个HandlerA作为头,然后内部的setHandler方法设置下一个的HandlerB,尾指向HandlerB,当继续有处理器add的时候,将其添加到HandlerB的setHandler方法中,然后尾指向HandlerC,以此类推。
1.1 定义一个抽象处理器类
/**
* 处理器:子类去处理执行,如果处理完毕则结束;否则,交给下一个处理器执行
*/
public abstract class Handler {
private Handler next = null;
/**
* 注入子类处理器
*/
public void setNext(Handler next) {
this.next= next;
}
public Handler getNext() throws NullPointerException{
if (this.next != null) {
return this.next;
} else {
throw new NullPointerException("没有设置next!!!请设置在调用");
}
}
/**
* 抽象方法:由子类个性化实现
*/
public abstract void handle();
}
1.2 实现这个抽象类。
/**
* A处理器
*/
public class HandlerA extends Handler {
@Override
public void handle() {
System.out.println("执行A处理器业务逻辑===");
System.out.println("执行A处理器业务逻辑成功!");
getNext().handle();
}
}
/**
* B处理器
*/
public class HandlerB extends Handler {
@Override
public void handle() {
System.out.println("执行B处理器业务逻辑===");
System.out.println("执行B处理器业务逻辑成功!");
getNext().handle();
}
}
/**
* C处理器
*/
public class HandlerC extends Handler {
@Override
public void handle() {
System.out.println("执行C处理器业务逻辑===");
System.out.println("执行C处理器业务逻辑成功!");
//getNext().handle();
}
}
1.3 实现一个链表类型的责任链。
/**
* 责任链:链表
*/
public class HandlerChain extends Handler {
private Handler head = null; //头
private Handler tail = null; //尾
public void addHandler(Handler handler) {
handler.setNext(null);
if (null == head) {
//第一次添加的时候
head = handler;
tail = handler;
} else{
//这一步操作,将尾部的Handler内的成员handler变量赋值为下一个Handler
tail.setNext(handler);
tail = handler;
}
}
public void handle() {
if (null != head) {
head.handle();
}
}
}
1.4 使用(也可以用工厂模式简化使用难度)
public class Test{
public static void main(String[] args) {
HandlerChain handler = new HandlerChain();
handler.addHandler(new HandlerA());
handler.addHandler(new HandlerB());
handler.addHandler(new HandlerC());
handler.handle();
}
}
2、基于数组
2.1 定义一个抽象处理器类
/**
* handler的接口
*/
public interface IHandler {
/**
* 执行处理
*/
void handle(IHandler next);
}
2.2 实现这个接口。
/**
* A处理器
*/
public class HandlerA implements IHandler {
@Override
public void handle(IHandler next) {
System.out.println("执行A处理器=====");
System.out.println("A处理成功!");
next.handle();
}
}
/**
* B处理器
*/
public class HandlerB implements IHandler {
@Override
public void handle(IHandler next) {
System.out.println("执行B处理器=====");
System.out.println("B处理成功!");
next.handle();
}
}
/**
* C处理器
*/
public class HandlerC implements IHandler {
@Override
public void handle(IHandler next) {
System.out.println("执行C处理器=====");
System.out.println("C处理成功!");
next.handle();
}
}
2.3 实现一个数组类型的责任链。
/**
* 责任链:数组
*/
public class HandlerChain implements IHandler{
private List<IHandler> handlers = new ArrayList<>();
// 有可能出现线程安全问题,要注意
private int index = 0;
public HandlerChain addHandler(IHandler handler) {
handlers.add(handler);
return this;
}
@Override
public void handle(IHandler next) {
if (index >= filters.size()) {
return;
}
MyFilter filter = filters.get(index);
index++;
filter.handle(next);
// 进行回溯,否则没法进行重新过滤了
index--;
}
}
2.4 使用(也可以用工厂模式简化使用难度)
public class Test{
public static void main(String[] args) {
HandlerChain handler = new HandlerChain();
handler.addHandler(new HandlerA());
handler.addHandler(new HandlerB());
handler.addHandler(new HandlerC());
handler.handle(handler);
}
}
三、责任链总结
优点
- 允许动态的增加和删除职责,且由用户决定是否执行某种操作。
- 实现了被操作对象和操作的解耦。
- 一个命令可以被多个处理器执行,例如各种框架中的拦截器
缺点
- 系统复杂度提高,容易出错。即组链时候不合理,可能导致请求得不到执行,还有可能将链变成一个环,请求在里面循环,永远都完不了。
- 影响性能,出现递归调用,容易造成栈溢出
适用场景
- 由用户确定实现怎样的处理的流程。
- 不确定是否需要添加这种处理的情况。
- 把任务分解,大的任务分解成小步进行处理。