easyexel 导入数据校验(责任链模式)

72 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

责任链模式

最近在做一个Excel导入的功能,需要校验的数据很多,有该次导入数据本身是否重复的,有的从数据库中查询,当然还有数据类型校验,当然用ifelse来写,也没问题 但,为了代码的优雅和可扩展性,我选择尝试一下责任链模式,责任链主要是为了解决一组服务中先后执行处理关系

是将链中每个节点看做一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。属于行为型模式。

责任链模式的优缺点

1.优点
  1. 大量减少ifelse
  2. 逻辑清晰明了,添加删除节点,改变节点顺序方便快捷
  3. 请求和处理解耦
  4. 请求处理者只需关注自己感兴趣的请求,对于不感兴趣的请求,直接发给下一节点
  5. 易扩展新的请求处理类,符合开闭原则
1.缺点
  1. 责任链太长导致整体处理时间太长
  2. 如果判断的东西太多,容易造成类保证
  3. 如果每个判断逻辑简单,可能造成一个类只做了一个简单的数值判断
  4. 如果节点对象在循环链接,可能会造成死循环

使用

@Data
public class User {
 private String userName;
 private String password;
 private Integer age;
}
/**
 * 责任链处理器抽象类
 * @param <T>
 */
@Data
public abstract class Handler<T> {

    protected Handler next;

    //寻找下一个校验节点
    private void next(Handler next) {
        this.next = next;
    }

    public abstract void doHandler(User m);

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

        public Builder<T> 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<T> build() {
            return this.head;
        }
    }
}

/**
 * 登录校验处理器
 */
public class LoginHandler extends Handler {

    @Override
    public void doHandler(User member) {
        if (StringUtils.isEmpty(member.getUserName()) ||
                StringUtils.isEmpty(member.getPassword())) {
            System.out.println("请填写用户名或密码");
            return;
        }
        if (null != next) {
            next.doHandler(member);
        }
    }
}


/**
 * 年龄校验处理器
 */
public class AgeHandler extends Handler {

    public AgeHandler() {
    }

    //建造者模式 再建造一些责任链中某个单位的子链路
    public AgeHandler(Handler.Builder builder) {
        builder.addHandler(new AgeMinHandler())
               .addHandler(new AgeMaxHandler());
    }
    @Override
    public void doHandler(User member) {
        if (member.getAge() == null || member.getAge() == 0) {
            System.out.println("请填写年龄");
            return;
        }
        if (null != next) {
            next.doHandler(member);
        }

    }

    public static class AgeMinHandler extends Handler {

        @Override
        public void doHandler(User member) {
            if (member.getAge() < 22 ) {
                System.out.println("还没毕业 不要");
                return;
            }
            if (null != next) {
                next.doHandler(member);
            }

        }

    }

    public static class AgeMaxHandler extends Handler {

        @Override
        public void doHandler(User member) {
            if (member.getAge() > 35) {
                System.out.println("年龄太大 不要");
                return;
            }
            if (null != next) {
                next.doHandler(member);
            }
        }
    }

}

public class HandlerTest {
    public static void main(String[] args) {
        User member = new User();
        member.setUserName("admin");
        member.setPassword("123");
        member.setAge(36);
        Handler.Builder builder = new Handler.Builder();
        //添加链路节点
        builder.addHandler(new AgeHandler(builder))
        .addHandler(new LoginHandler());

        builder.build().doHandler(member);
    }
}

我们预设了责任链,一个请求就会验证这个责任链一步步向后传递,要么被某个节点终止,要么直到最后处理完