单体【其他模式】

单体

public class Monad {
    /**
     * Monad pattern【单体模式】:
     * Monad pattern 定义了一个单体结构,它支持在管道中一步步地处理数据。
     * Monad 由一个类型构造函数和两个操作组成,
     * bind():绑定已经解包的值,将其输入处理函数,并输出新的包裹值。
     * get():获取最终的处理结果
     */
    @Test(expected = IllegalStateException.class)
    public void all() {
        final User user = User.of("zxd", -1);
        Validator.of(user)
        .validate(User::getName, StringUtils::isNotBlank, "name can not be blank")
        .validate(User::getAge, age -> age >= 1 && age <= 120, "age is invalid")
        .get();
    }
}

@Value(staticConstructor = "of")
class User {
    private String name;
    private int age;
}

class Validator<T> {
    private final T t;
    private final List<Exception> exceptions = Lists.newArrayList();

    private Validator(T t) {
        this.t = t;
    }

    public static <T> Validator<T> of(T t) {
        return new Validator<>(Objects.requireNonNull(t));
    }

    public Validator<T> validate(Predicate<T> predicate, String message) {
        if (!predicate.test(t)) {
            exceptions.add(new IllegalStateException(message));
        }
        return this;
    }

    public <U> Validator<T> validate(Function<T, U> mapper, Predicate<U> predicate, String message) {
        return validate(mapper.andThen(predicate::test)::apply, message);
    }

    public T get() throws IllegalStateException {
        if (exceptions.isEmpty()) {
            return t;
        }
        final IllegalStateException e = new IllegalStateException();
        exceptions.forEach(e::addSuppressed);
        throw e;
    }
}

posted on 2019-01-05 12:01  竺旭东  阅读(90)  评论(0编辑  收藏  举报

导航