• 责任链模式


    一、责任链模式

    1、定义

    责任链模式(Chain of Responsibility Pattern),是指将链中每一个节点都看作一个对象,每个节点处理的请求均不同,且内部自动维护下一个节点对象。当一个请求从链式的首端发出时,会沿着责任链预设的路径依次传递到每一个节点对象,直到被链中的某个对象处理为止,属于行为型设计模式。

    责任链模式的本质是解耦请求与处理,让请求在处理链中能进行传递与处理。

    2、结构

    (1)模式的结构

    主要角色如下:

    • 抽象处理者(Handler):定义一个请求处理的方法,并维护一个下一处理节点的 Handler对象的引用。
    • 具体处理者(ConcreteHandler):对请求进行处理,如果不感兴趣,则进行转发到它的下一个节点。

    3、优缺点

    优点:

    • 将请求与处理解耦。
    • 请求处理者只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一个节点处理。
    • 链路结构灵活,可以通过盖帘链结构动态地新增或删减责任。
    • 易扩展,符合开闭原则

    缺点:

    • 责任链太长或者处理时间太长,会影响整体性能。
    • 如果节点对象存在循环引用,则会造成死循环,导致系统崩溃。

    4、使用场景

    • 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
    • 在不明确指定接收者的情况下,向多个对象中的一个提交请求。
    • 可动态指定一组对象处理请求。

    5、在框架源码中使用

    • Java中的 Filter类。
    • Spring Security或者Shiro都用到责任链模式。

    二、模式的通用实现

    代码如下:

    public class ChainOfResponsibilityPattern {
        public static void main(String[] args) {
            Handler handlerA = new ConcreteHandlerA();
            Handler handlerB = new ConcreteHandlerB();
    
            handlerA.setNextHandler(handlerB);
    
            handlerA.doHandle("A");
            System.out.println("----------");
            handlerA.doHandle("B");
            System.out.println("----------");
            handlerA.doHandle("C");
        }
    }
    
    //抽象处理者
    abstract class Handler{
        // 下一个节点对象引用
        protected Handler nextHandler;
    
        public void setNextHandler(Handler nextHandler) {
            this.nextHandler = nextHandler;
        }
    
        public abstract void doHandle(String request);
    }
    
    // 具体处理者
    class ConcreteHandlerA extends Handler{
    
        @Override
        public void doHandle(String request) {
            if("A".equals(request)){
                System.out.println("ConcreteHandlerA 处理请求");
                return;
            }
            if(this.nextHandler != null){
                this.nextHandler.doHandle(request);
            }
        }
    }
    
    class ConcreteHandlerB extends Handler{
    
        @Override
        public void doHandle(String request) {
            if("B".equals(request)){
                System.out.println("ConcreteHandlerB 处理请求");
                return;
            }
            if(this.nextHandler != null){
                this.nextHandler.doHandle(request);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    在这里插入图片描述

    三、模式的应用实例

    已授权登录校验为例。

    @Data
    public class User {
    	private String username;
    
    	private String pazzWord;
    
    	private String roleName;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    示例一

    责任链模式编写:

    (1)抽象处理类

    public abstract class WebHandler {
        protected WebHandler chain;
    
        public void next(WebHandler Handler){
            this.chain = Handler;
        }
    
        public abstract void doHandle(User user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (2)具体处理类

    public class ValidateWebHandler extends WebHandler{
        @Override
        public void doHandle(User user) {
            if(user == null){
                System.out.println("用户为空");
                return;
            }
            if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPazzWord())){
                System.out.println("用户名或者密码为空");
                return;
            }
            System.out.println("用户信息校验成功。向下一个执行");
            this.chain.doHandle(user);
        }
    }
    
    public class LoginWebHandler extends WebHandler{
        @Override
        public void doHandle(User user) {
            System.out.println("查询数据库,用户登录成功。");
            user.setRoleName("admin");
            System.out.println("查询用户角色,向下一个执行");
            this.chain.doHandle(user);
        }
    }
    
    public class AuthWebHandler extends WebHandler{
        @Override
        public void doHandle(User user) {
            if("admin".equals(user.getRoleName())){
                System.out.println("管理员上线,允许进行全部操作");
                return;
            }else{
                System.out.println("普通用户上线,正常权限进行操作");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    (3)测试

        public static void main(String[] args) {
            WebHandler validateWebHandler = new ValidateWebHandler();
            WebHandler loginWebHandler = new LoginWebHandler();
            WebHandler authWebHandler = new AuthWebHandler();
    
            validateWebHandler.next(loginWebHandler);
            loginWebHandler.next(authWebHandler);
    
            User user = new User();
            user.setUsername("赵云");
            user.setPazzWord("123456");
            validateWebHandler.doHandle(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    示例二

    针对复杂结构的责任链组装。我们可以结合建造者模式一起使用。

    (1)抽象处理类

    public abstract class WebHandler2<T> {
    	protected WebHandler2 chain;
    
    	private void next(WebHandler2 Handler) {
    		this.chain = Handler;
    	}
    
    	public abstract void doHandle(User user);
    
    	public static class Builder<T> {
    		private WebHandler2<T> head;
    		private WebHandler2<T> tail;
    
    		public Builder<T> addWebHandler(WebHandler2<T> webHandler2) {
    			if (this.head == null) {
    				this.head = this.tail = webHandler2;
    				return this;
    			}
    			this.tail.next(webHandler2);
    			this.tail = webHandler2;
    			return this;
    		}
    
    		public WebHandler2<T> build() {
    			return this.head;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    (2)具体处理类

    public class ValidateWebHandler extends WebHandler2{
        @Override
        public void doHandle(User user) {
            if(user == null){
                System.out.println("用户为空");
                return;
            }
            if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPazzWord())){
                System.out.println("用户名或者密码为空");
                return;
            }
            System.out.println("用户信息校验成功。向下一个执行");
            this.chain.doHandle(user);
        }
    }
    
    public class LoginWebHandler extends WebHandler2{
        @Override
        public void doHandle(User user) {
            System.out.println("查询数据库,用户登录成功。");
            user.setRoleName("admin");
            System.out.println("查询用户角色,向下一个执行");
            this.chain.doHandle(user);
        }
    }
    
    public class AuthWebHandler extends WebHandler2{
        @Override
        public void doHandle(User user) {
            if("admin".equals(user.getRoleName())){
                System.out.println("管理员上线,允许进行全部操作");
                return;
            }else{
                System.out.println("普通用户上线,正常权限进行操作");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    (3)测试

        public static void main(String[] args) {
            WebHandler2.Builder<Object> webHandler2 = new WebHandler2.Builder<>();
            webHandler2.addWebHandler(new ValidateWebHandler2())
                    .addWebHandler(new LoginWebHandler2())
                    .addWebHandler(new AuthWebHandler2());
    
            User user = new User();
            user.setUsername("赵子龙");
            user.setPazzWord("123456");
            webHandler2.build().doHandle(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    – 求知若饥,虚心若愚。

  • 相关阅读:
    arthas-线上排查问题工具
    CH1-模型训练优化
    吴恩达机器学习系列课程笔记——第十二章:支持向量机(Support Vector Machines)
    The user specified as a definer (‘platformadmin‘@‘%‘) does not exist.
    OBU与千寻魔方的定位性能分析
    微信小程序毕业设计论文医院挂号预约系统+后台管理系统项目源代码
    python版局域网端口扫描
    YOLOv7 在 ML.NET 中使用 ONNX 检测对象
    RK平台ADB不识别问题排查
    EmEditor文本编辑器添加宏,实现xml报文格式化显示
  • 原文地址:https://blog.csdn.net/qq_42402854/article/details/128212214