什么是责任链:
责任链是一种思想,类比现实生活中,在一种需要审批的业务中,用户提交了请求之后就不用管了,至于后续业务中具体是谁审批通过的,用户并不关心也无从得知,只要最终审批通过了就可以。
映射到责任链的这一种设计模式上,解释来说就是:某一个提交的请求对象,在得到最终的结果之前,中间可能要经过多个对象的处理,这些处理请求的对象前后之间存在前置和后继的关系,连接在一起就形成了一个处理链条,对于链条上的每个节点来说,只要能够处理请求,就可以得到请求的结果并返回,否则就把请求继续移交给后续的处理对象,直到最终获取到请求的结果
比如我们熟知的servlet中的filter组件中,就存在责任链模式,还有springsecurity中,大量的责任链模式的使用,下面通过两个简单的案例简要说说责任链模式的使用
案例分享一
需求:用户提交自己的身份证号后,就可以知道自己是否是北京、上海、广州、深圳的户口
1、公共处理者接口
public interface Handler {
public abstract void handlerRequest(String number);
public abstract void setNextHandler(Handler handler);
}
公共的处理者部分如果没有特殊的公共业务,可以直接使用接口即可,否则一般使用抽象类
2、具体的handler,即责任链上的不同的处理器
2.1 BeiJingHandler
public class BeiJingHandler implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public BeiJingHandler() {
numberList = new ArrayList<>();
numberList.add("京-0001");
numberList.add("京-0002");
numberList.add("京-0003");
}
@Override
public void handlerRequest(String number) {
if (numberList.contains(number)) {
System.out.println("该人是北京户口");
} else {
System.out.println("该人是不北京户口");
if(handler != null){
//将请求传递给下一个处理者
handler.handlerRequest(number);
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
真实情况下,资源池可以从数据库或者其他的存储数据的地方获取
2.2 ShangHaiHandler
public class ShangHaiHandler implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public ShangHaiHandler() {
numberList = new ArrayList<String>();
numberList.add("上海-0001");
numberList.add("上海-0002");
numberList.add("上海-0003");
}
@Override
public void handlerRequest(String number) {
if (numberList.contains(number)) {
System.out.println("该人是上海户口");
} else {
System.out.println("该人不是上海户口");
if(handler != null){
//将请求传递给下一个处理者
handler.handlerRequest(number);
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
2.3 ShangHaiHandler
public class GuangzhouHandler implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public GuangzhouHandler() {
numberList = new ArrayList<String>();
numberList.add("广-0001");
numberList.add("广-0002");
numberList.add("广-0003");
}
@Override
public void handlerRequest(String number) {
if (numberList.contains(number)) {
System.out.println("该人是广州户口");
} else {
System.out.println("该人不是广州户口");
if(handler != null){
//将请求传递给下一个处理者
handler.handlerRequest(number);
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
2.4 ShenZhenHandler
public class ShenZhenHandler implements Handler {
private Handler handler;
private ArrayList<String> numberList;
public ShenZhenHandler() {
numberList = new ArrayList<String>();
numberList.add("深-0001");
numberList.add("深-0002");
numberList.add("深-0003");
}
@Override
public void handlerRequest(String number) {
if (numberList.contains(number)) {
System.out.println("该人是深圳户口");
} else {
System.out.println("该人不是深圳户口");
if(handler != null){
//将请求传递给下一个处理者
handler.handlerRequest(number);
}
}
}
@Override
public void setNextHandler(Handler handler) {
this.handler = handler;
}
}
如果后续添加更多的处理器,继续加进去即可,扩展起来很方便
3、测试一下上述的代码
public class AppTest {
public static void main(String[] args) {
BeiJingHandler firstHandler = new BeiJingHandler();
ShangHaiHandler secondHandler = new ShangHaiHandler();
GuangzhouHandler thirdHandler = new GuangzhouHandler();
ShenZhenHandler fourthHandler= new ShenZhenHandler();
firstHandler.setNextHandler(secondHandler);
secondHandler.setNextHandler(thirdHandler);
thirdHandler.setNextHandler(fourthHandler);
firstHandler.handlerRequest("深-0002");
}
}
通过这样一个简单的需求,用户提交了一个需求后,系统会根据各自处理器的功能,最终获取到自己的结果
案例分享二
需求说明:在一个需要审批的业务中,不同的角色具有不同的审批权限,比如同学提交的申请表到班长那里,班长提交的申请表再转到班主任,班主任的请求转到院长那里,同学无法审批班长的请求,班长也无法审批班主任的请求
1、抽象请求
由于需要在后续业务中通过获取请求对象的级别,即一个公共的业务,这里采用了抽象类
public abstract class AbstractRequest {
String content = "";
public AbstractRequest(){
this.content = content;
}
public String getContent() {
return content;
}
//获取处理请求的级别
public abstract int getRequestLever();
}
2、抽象责任处理器
public abstract class AbstractHandler {
// 责任链的下一个节点,即处理者
private AbstractHandler nextHandler = null;
// 捕获具体请求并进行处理,或是将请求传递到责任链的下一级别
public final void handleRequest(AbstractRequest request) {
// 若该请求与当前处理者的级别相对应,则由自己进行处理
if (this.getHandlerLever() == request.getRequestLever()) {
this.handlered(request);
} else {
// 当前处理者不能胜任,则传递至职责链的下一节点
if (nextHandler != null) {
System.out.println("当前处理者 0" + this.getHandlerLever() + "不足以处理请求 0" + request.getRequestLever());
// 这里使用了递归调用
this.nextHandler.handleRequest(request);
} else {
System.out.println("职责链上的所有处理者都不能胜任该请求...");
}
}
}
// 设置责任链中的下一个处理者
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
// 获取当前处理者的级别
public int getHandlerLever() {
return 0;
}
// 定义链中每个处理者具体的处理方式
protected abstract void handlered(AbstractRequest request);
}
3、获取不同请求的请求级别
这里假如有3个级别的请求处理器:
3.1 请求处理器1
public class Request01 extends AbstractRequest {
public Request01(String content) {
this.content = super.getContent();
}
@Override
public int getRequestLever() {
return 1;
}
}
public class Handler01 extends AbstractHandler{
@Override
public int getHandlerLever() {
return 1;
}
@Override
protected void handlered(AbstractRequest request) {
System.out.println("处理者-01 同学 " + request.getContent() + "\n");
}
}
3.2 请求处理器2
public class Request02 extends AbstractRequest {
public Request02(String content) {
this.content = super.getContent();
}
@Override
public int getRequestLever() {
return 2;
}
}
public class Handler02 extends AbstractHandler {
@Override
public int getHandlerLever() {
return 2;
}
@Override
protected void handlered(AbstractRequest request) {
System.out.println("处理者-02 班长 " + request.getContent() + "\n");
}
}
3.3 请求处理器3
public class Request03 extends AbstractRequest {
public Request03(String content) {
this.content = super.getContent();
}
@Override
public int getRequestLever() {
return 3;
}
}
public class Handler03 extends AbstractHandler {
@Override
public int getHandlerLever() {
return 3;
}
@Override
protected void handlered(AbstractRequest request) {
System.out.println("处理者-03 班主任 " + request.getContent() + "\n");
}
}
4、测试类
public class TestMain {
/*public static void main(String[] args) {
// 创建请求并提交到指责链中进行处理
AbstractRequest request01 = new Request01("同学请求");
AbstractRequest request02 = new Request02("班长请求");
AbstractRequest request03 = new Request03("主任请求");
// 创建指责链的所有节点
AbstractHandler handler01 = new Handler01();
AbstractHandler handler02 = new Handler02();
AbstractHandler handler03 = new Handler03();
// 进行链的组装,即头尾相连,一层套一层
handler01.setNextHandler(handler02);
handler02.setNextHandler(handler03);
// 每次提交都是从链头开始遍历
//handler01.handleRequest(request01);
handler01.handleRequest(request02);
//handler01.handleRequest(request03);
}*/
public static void handleRequest(String requestName) {
// 创建指责链的所有节点
AbstractHandler handler01 = new Handler01();
AbstractHandler handler02 = new Handler02();
AbstractHandler handler03 = new Handler03();
// 进行链的组装,即头尾相连,一层套一层
handler01.setNextHandler(handler02);
handler02.setNextHandler(handler03);
if("同学请求".equals(requestName)){
AbstractRequest request01 = new Request01("同学请求");
handler01.handleRequest(request01);
}
if("班长请求".equals(requestName)){
AbstractRequest request02 = new Request02("班长请求");
handler01.handleRequest(request02);
}
if("主任请求".equals(requestName)){
AbstractRequest request03 = new Request03("主任请求");
handler01.handleRequest(request03);
}
}
public static void main(String[] args) {
String requestName = "班长请求";
handleRequest(requestName);
}
}
处理请求的时候一般是从第一个处理器开始,责任链中的处理器一旦确定,就需要提前将他们的前后置关系设定好,之后不同的请求过来了只需要从第一个handler开始
在真实的业务中,责任链上的各个处理器,是根据需求提前设计好的,每个处理器具体要处理哪一部分的功能,比如处理器1校验参数合法性,处理器2校验token,处理器3校验某个参数是否存在等,都是动态进行的,责任链模式也正是具备这种热插拔、动态扩展的特性使得它在一些特定的场合中很有效
本篇简单分享了责任链模式的使用,更深入的比如像springsecurity中是如何使用这种模式的,有兴趣的同学可以继续深入研究,最后感谢观看!
来源:CSDN
作者:神秘的葱
链接:https://blog.csdn.net/zhangcongyi420/article/details/103457069