设计模式之责任链模式

575 阅读2分钟

话不多说,开始今天的文章

责任链模式的定义:

责任链是一种行为性的设计模式
通俗点讲:责任链其实就是将连续做处理的单元串成一条链,从链头一直到链尾执行下去或者中途不符合条件跳出

以下将通过登陆需求引出责任链模式,但并不是说这种情况下责任链模式会更加好

用户登陆时的需求:

1.判断用户是否存在
2.判断用户状态是否正常
3.判断密码是否正确

解决方案:

MemberDO memberDO = memberMapper.selectByEmail(email);
//1.判断用户是否存在
ObjectUtil.isNullToMessage(memberDO, ResultEnum.USER_NO_EXIT);
//2.判断用户状态是否正常
if (!Objects.equals(UserConstant.USER_STATUS_NORMAL,memberDO.getStatus())){
   throw new ResultException(ResultEnum.USER_DISABLE);
}
//3.判断密码是否正确
if (!Objects.equals(memberDO.getPassword(),EncryptionUtil.EncoderPwdByMd5(loginDTO.getPassword(),null))){
   throw new ResultException(ResultEnum.USER_PASSWORD_ERROR);
}

责任链模式解决方案

MemberDO memberDO = memberMapper.selectByEmail(email);
        loginDTO.setMemberDO(memberDO);
AbstractHandler.Builder builder = new AbstractHandler.Builder();
        //1.判断用户是否存在
        builder.addHandler(new UserHandler())
                //2.判断用户状态是否正常
                .addHandler(new VerifyPermissionHandler())
                //3.判断密码是否正确
                .addHandler(new AuthHandler())
                //添加入参
                .build().doHandler(loginDTO);

public abstract class AbstractHandler<T> {

    protected AbstractHandler<T> next = null;

    /**
     * 责任链入参
     * @param loginDTO 登陆实体类
     */
    public abstract void doHandler(LoginDTO loginDTO);

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

    public static class Builder<T> {
        private AbstractHandler<T> head;
        private AbstractHandler<T> tail;

        public Builder<T> addHandler(AbstractHandler handler) {
            if (this.head == null) {
                this.head = handler;
                this.tail = handler;
            } else {
                this.tail.next(handler);
                this.tail = handler;
            }
            return this;
        }

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

具体处理者

public class UserHandler extends AbstractHandler {

    @Override
    public void doHandler(LoginDTO loginDTO) {
        MemberDO memberDO = loginDTO.getMemberDO();
        //判断用户是否存在
        ObjectUtil.isNullToMessage(memberDO, ResultEnum.USER_NO_EXIT);
        if (next != null){
            next.doHandler(loginDTO);
        }
    }
}

public class VerifyPermissionHandler extends AbstractHandler {

    @Override
    public void doHandler(LoginDTO loginDTO) {
        MemberDO memberDO = loginDTO.getMemberDO();
        //判断用户状态
        if (Objects.equals(UserConstant.USER_STATUS_NORMAL,memberDO.getStatus())){
            throw new ResultException(ResultEnum.USER_DISABLE);
        }
        if (next != null){
            next.doHandler(loginDTO);
        }
    }
}


public class AuthHandler extends AbstractHandler {

    @Override
    public void doHandler(LoginDTO loginDTO) {
        MemberDO memberDO = loginDTO.getMemberDO();
        //查看密码是否正确
        if (!Objects.equals(memberDO.getPassword(),EncryptionUtil.EncoderPwdByMd5(loginDTO.getPassword(),null))){
            throw new ResultException(ResultEnum.USER_PASSWORD_ERROR);
        }
        return;
    }
}

优点:

  1. 降低耦合度
  2. 增加新的处理类方便
  3. 允许动态的修改处理类顺序以及个数

缺点:

  1. 链路太长性能受到影响
  2. 容易造成循环调用