设计模式回顾之责任链模式

本文通过一个登录验证的实例介绍了责任链模式的使用。责任链模式允许在运行时动态指定请求处理对象,实现了请求与处理的解耦。在登录验证场景中,包括了用户名密码校验、登录验证和权限验证三个处理节点,每个节点根据条件决定是否继续处理或转发请求。通过Handler类的抽象和具体实现,构建了一条处理链,最终实现了灵活的验证流程。
摘要由CSDN通过智能技术生成

介绍

责任链模式是将每一个节点看作一个对象,每个节点处理的请求均不同,且节点内部维护下一个节点对象。当请求进来时,从首端进入,沿着链的路径依次传递给每一个节点对象,直到有对象处理这个请求位置。

责任链模式主要是解耦了请求与处理,客户只需要将请求发送到链上即可,无需关心请求的具体内容和处理细节,请求会自动进行传递直至有节点对象进行处理。

适用场景:

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

责任链模式中几个重要的角色:

  • 抽象处理类:定义请求处理的方法,并维护下一个处理节点引用。
  • 具体处理:对请求进行处理,如果不归本类管,则进行转发。

实战

接下来我们运用责任链模式来做一个登录验证的流程demo。

顶层定义

package handlerChain;

/**
 * @author chengyanqi
 * @date 2021/8/18 22:45
 */
public abstract class Handler {
    protected Handler chain;

    public void next(Handler handler) {
        this.chain = handler;
    }

    public abstract void doHandler(User user);

    public static class Builder{
        private Handler head;
        private Handler tail;

        public Builder addHandler(Handler handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return this;
        }

        public Handler build() {
            return this.head;
        }
    }
}

责任链各个节点的具体实现

package handlerChain;

import org.springframework.util.StringUtils;

/**
 * @author chengyanqi
 * @date 2021/8/18 22:51
 */
public class ValidateHandler extends Handler {
    @Override
    public void doHandler(User user) {
        if (StringUtils.isEmpty(user.getUserName()) || StringUtils.isEmpty(user.getPassword())) {
            System.out.println(user.getUserName() + "用户名密码为空!");
            return;
        }
        System.out.println(user.getUserName() + "用户名密码校验成功往下执行~");
        chain.doHandler(user);
    }
}

package handlerChain;

/**
 * @author chengyanqi
 * @date 2021/8/18 23:05
 */
public class LoginHandler extends Handler {
    @Override
    public void doHandler(User user) {
        if (!user.getPassword().equals("password")) {
            System.out.println(user.getUserName() + "密码校验失败!");
            return;
        }
        System.out.println(user.getUserName() + "登录成功~");
        chain.doHandler(user);
    }
}

package handlerChain;

/**
 * @author chengyanqi
 * @date 2021/8/18 23:07
 */
public class AuthHandler extends Handler {
    @Override
    public void doHandler(User user) {
        if (!"管理员".equals(user.getRoleName())) {
            System.out.println(user.getUserName() + "没有操作权限!");
            return;
        }
        System.out.println(user.getUserName() + "操作成功!");
    }
}

构建责任链业务代码

package handlerChain;

/**
 * @author chengyanqi
 * @date 2021/8/18 23:39
 */
public class UserHandlerChain {
    public void login(String userName, String password, String roleName) {

        Handler.Builder builder = new Handler.Builder();
        builder.addHandler(new ValidateHandler())
                .addHandler(new LoginHandler())
                .addHandler(new AuthHandler());

        builder.build().doHandler(new User(userName, password, roleName));
    }
}

测试

package handlerChain;

/**
 * @author chengyanqi
 * @date 2021/8/18 23:45
 */
public class Test {
    public static void main(String[] args) {
        UserHandlerChain chain = new UserHandlerChain();
        chain.login("张三", "pasword", "管理员");
        chain.login("李四", "password", "管理员2");
        chain.login("王五", "password", "管理员");

    }
}

张三用户名密码校验成功往下执行~
张三密码校验失败!
李四用户名密码校验成功往下执行~
李四登录成功~
李四没有操作权限!
王五用户名密码校验成功往下执行~
王五登录成功~
王五操作成功!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程大帅气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值