责任链模式
一. 说明
责任链模式是一种行为型模式,它允许将请求沿着处理器链进行传递处理,处理器能处理则处理,处理不了的就让下一个处理器处理,直到处理成功或链完毕。这种模式可以将某个功能根据职责拆解开来,解耦处理器之间的关系。
在各种框架中责任链模式进行着大量的引用,也是比较常见的设计模式,生活中我们OA系统的审批流程、儿时的游戏击鼓传花等都是责任链模式。
责任链模式的结构主要是一个基类 + 多个处理器链 构成,基类抽象让处理器具备设置下一个处理器的能力,示意图如下:
二.应用场景
- OA系统的审批流程
- Spring中应用了大量的责任链模式,像AOP的思想,MVC中的DispatchServlet等
- Netty中的Handler链
- web开发中的过滤器链和拦截器链
- 一些框架中的加工处理都有pipeline
三.代码示例
我们先用简单的例子来表述以下责任链模式,以审批流程为例,我们在请假时需要上面三层领导审批:首先是经理,再是总监,最后是总经理。
先创建一个基类,表示管理者
public abstract class Manager {
private Manager superior;
public void setSuperior(Manager superior) {
this.superior = superior;
}
public Manager getSuperior() {
return superior;
}
//表示请假动作
public abstract boolean doHandler(String uid);
}
再创建三个具体管理者:经理,总监,CEO
public class CommonManager extends Manager {
@Override
public boolean doHandler(String uid) {
//一律放行
System.out.println("经理审批通过");
Manager superior = super.getSuperior();
if (superior != null) {
return superior.doHandler(uid);
}
return true;
}
}
public class DirectorManager extends Manager{
@Override
public boolean doHandler(String uid) {
if ("10001".equals(uid)) {
System.out.println("总监审批不通过");
return false;
}
System.out.println("总监审批通过");
Manager superior = super.getSuperior();
if (superior != null) {
return superior.doHandler(uid);
}
return true;
}
}
public class CeoManager extends Manager{
@Override
public boolean doHandler(String uid) {
if ("10002".equals(uid)) {
System.out.println("CEO审批不通过");
return false;
}
System.out.println("CEO审批通过");
Manager superior = super.getSuperior();
if (superior != null) {
return superior.doHandler(uid);
}
return true;
}
}
编写测试代码,需要注意他们的层级指向
public static void main(String[] args) {
CommonManager commonManager = new CommonManager();
DirectorManager directorManager = new DirectorManager();
CeoManager ceoManager = new CeoManager();
//设置审批链
commonManager.setSuperior(directorManager);
directorManager.setSuperior(ceoManager);
System.out.println("10001审批结果如下:");
commonManager.doHandler("10001");
System.out.println("----------------");
System.out.println("10002审批结果如下:");
commonManager.doHandler("10002");
System.out.println("----------------");
System.out.println("10003审批结果如下:");
commonManager.doHandler("10003");
System.out.println("----------------");
}
测试结果如下,符合预期
通过上面的例子,我们可以观察到,层级之间通过指向将关系链接,从而解耦了管理者之间具体的关联,三层关系我们保留两层也好,多加一层也好,层与层之间互不影响,只需要更改层的指向即可,是比较好的设计思想。
四. 总结
责任链模式满足单一职责原则和开放封闭原则,我们更改代码也只需要更改链中的指向,链中的每一个节点都只处理自己的业务,节点与节点之间互不影响,它使对象之间的关系更加清晰,外部调用也无须知道整个链是如何编织的。