Java设计模式之-责任链设计模式

责任链设计模式

定义:

为请求定义一条处理链,请求者不用关心链中的执行过程与方法,当链中的一个请求成功了,会继续向下一个链执行,直到调用链结束。

举个栗子

以我们常用的鉴权为例:请求token进入,首先判断token是否合法,再判断token是否过期,再判断用户是否有权限访问该接口。
token合法性校验结构图废话不多说,上代码:

  • 首先定义一个token对象,稍后会验证该token是否合法
/**
 * @date 2022/10/24 17:05
 */
public class Token {

    /**
     * 过期时间
     */
    private Date expirationTime;

    /**
     * 权限标识符
     */
    private List<String> auths;

    /**
     * token数据
     */
    private String data;

    public Date getExpirationTime() {
        return expirationTime;
    }

    public void setExpirationTime(Date expirationTime) {
        this.expirationTime = expirationTime;
    }

    public List<String> getAuths() {
        return auths;
    }

    public void setAuths(List<String> auths) {
        this.auths = auths;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

  • 抽象处理类

/**
 * 抽象处理类
 *
 * @date 2022/10/24 16:49
 */
public abstract class Handler<T> {
    protected Handler<?> nextHandler;

    public final void next(Handler<?> nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 处理函数
     */
    public abstract void doHandler(Token token);

}

  • 抽象处理类的具体实现类(token的合法性校验)
/**
 * token合法性校验
 *
 * @date 2022/10/24 17:20
 */
public class LegalAuthHandler<T> extends Handler<T> {

    /**
     * 处理函数
     *
     * @param token
     */
    @Override
    public void doHandler(Token token) {

        String data = token.getData();


        if (data != null && !"".equals(data)) {
            System.out.println("合法性校验通过");
            this.nextHandler.doHandler(token);

        } else {
            System.out.println("合法性校不通过,认证失败");
            return;
        }
    }


}
  • 抽象处理类的具体实现类(时间的过期认证)
/**
 * 时间认证
 *
 * @date 2022/10/24 17:20
 */
public class DateAuthHandler<T> extends Handler<T> {

    /**
     * 处理函数
     *
     * @param token
     */
    @Override
    public void doHandler(Token token) {
        Date expirationTime = token.getExpirationTime();

        if (Objects.isNull(expirationTime)) {
            System.out.println("验证失败");
            return;
        }

        boolean result = expirationTime.after(new Date());

        if (result) {
            System.out.println("时间认证通过");
            this.nextHandler.doHandler(token);
        } else {
            System.out.println("时间不通过,认证失败");
            return;
        }
    }


}
  • 抽象处理类的具体实现类(权限认证)
/**
 * 权限认证
 *
 * @date 2022/10/24 17:20
 */
public class SecurityAuthHandler<T> extends Handler<T> {

    /**
     * 处理函数
     *
     * @param token
     */
    @Override
    public void doHandler(Token token) {
        List<String> auths = token.getAuths();

        if (Objects.isNull(auths)) {
            System.out.println("权限认证不通过");
            return;
        }

        if (auths.contains("system:user:list")) {
            System.out.println("权限认证通过");
            this.nextHandler.doHandler(token);
        }

    }

}

  • 认证服务
/**
 * @date 2022/10/24 19:09
 */
public class AuthService {
    public void auth(Token token) {
        LegalAuthHandler<?> legalAuthHandler = new LegalAuthHandler<>();
        DateAuthHandler<?> dateAuthHandler = new DateAuthHandler<>();
        SecurityAuthHandler<?> securityAuthHandler = new SecurityAuthHandler<>();
        legalAuthHandler.next(dateAuthHandler);
        dateAuthHandler.next(securityAuthHandler);
        legalAuthHandler.doHandler(token);
    }
}
  • 测试

/**
 * @date 2022/10/24 19:07
 */
public class Test {
    public static void main(String[] args) {
        Token token = new Token();

        token.setExpirationTime(new Date(System.currentTimeMillis() + 1000));
        token.setData("aa.bb.cc");

        AuthService authService = new AuthService();
        authService.auth(token);


    }
}
结果:

合法性校验通过
时间认证通过
权限认证不通过

到此,恭喜你学会了责任链模式,后面的可以不看了,也可以拓展下。。。。。


接下来-----------------整合构建者模式,不然的话,我们在AuthService 写链式太麻烦了不是

  • 抽象处理类的具体实现类(结束处理器)
/**
 * 结束处理器
 *
 * @date 2022/10/25 9:25
 */
public class EndHandler<T> extends Handler<T> {
    @Override
    public void doHandler(Token token) {
        System.out.println("结束,通过");
    }
}
  • 改造一下抽象处理类Handler
/**
 * 抽象处理类
 *
 * @date 2022/10/24 16:49
 */
public abstract class Handler<T> {
    protected Handler<?> nextHandler;

    public final void next(Handler<?> nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 处理函数
     */
    public abstract void doHandler(Token token);

    public static class Builder<T> {

        private Handler<T> head;

        private Handler<T> current;

        public Builder<T> addHandler(Handler<T> handler) {
            //判断是否是第一个(如果只有一个,next就是空,防止后续判断空,所以给一个结束处理器)
            if (this.head == null) {
                this.head = this.current = handler;
                this.current.next(new EndHandler<>());
                return this;
            }
            
            this.current.next(handler);
            this.current = handler;
            return this;
        }

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

    }
}

  • 优化简化下AuthService类

/**
 * @date 2022/10/24 19:09
 */
public class AuthService {
    public void auth(Token token) {

        Handler.Builder<Handler<?>> builder = new Handler.Builder<>();

        builder
                .addHandler(new LegalAuthHandler<>())
                .addHandler(new DateAuthHandler<>())
                .addHandler(new SecurityAuthHandler<>());

        builder.build().doHandler(token);

    }
}

一个超级简单的责任链模式完成,搞定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值