如何概括一个静态的回合?

X教授:

我有以下情况:两个验证助手

StringValidationHelper ...

public class StringValidationHelper {

    public static Validation<String> notNull = 
        SimpleValidation.from(s -> s != null, "must not be null.");

    public static Validation<String> moreThan(int size) {
        return SimpleValidation.from(
            s -> s.length() >= size, 
            String.format ("must have more than %s chars.", size));
    }
        ... // More methods (lessThan, etc)}

...和NumberValidationHelper。

public class NumberValidationHelper {

    public static Validation<Number> notNull = 
        SimpleValidation.from(n -> n != null, "must not be null");

    public static <N extends Number & Comparable<N>> Validation<N> lowerThan(N max){
        return SimpleValidation.from(
            n -> n.compareTo(max) == -1,
            String.format("must be lower than %s.", max));
    }
    ... // More methods like (greaterThan, etc)}

来自的方法是一个静态工厂方法,它接收谓词,并且一条消息提示最终验证失败。

public class SimpleValidation<K> implements Validation<K>{
    private Predicate<K> predicate;
    private String onErrorMessage;

    private SimpleValidation(Predicate<K> predicate, String onErrorMessage) {
        this.predicate = predicate;
        this.onErrorMessage = onErrorMessage;
    }

    public static <K> SimpleValidation<K> from(Predicate<K> predicate, String onErrorMessage){
        return new SimpleValidation<>(predicate, onErrorMessage);
    }
    ... // Omitted for simplicity
}

借助Validation界面,您可以享受异常流畅的界面

    @FunctionalInterface
    public interface Validation<K> {

        ... // Omitted for simplicity

        default Validation<K> and(Validation<K> other) {
            return param -> {
                ValidationResult firstResult = this.test (param);
                return ! firstResult.isValid()? firstResult: other.test(param);
            };
        }
        ... // Omitted for simplicity
    }

因此,例如,我可以使用闭包notNull开始验证。

示例:使用NumberValidationHelper

public class MyValidate {
    void validate(int toValidate) {
        notNull.and(lowerThan(100)).test(toValidate).isValid();
    }
}

这验证框架我开发了基于文章。

好吧,notNull包含与类型无关的行为,因此我想删除这两个帮助程序的重复项。我在不丢失流体界面的情况下找不到明显的形状。

由于变量是静态的,因此,例如,您不能使用泛型并扩展行为。

public abstract class GenericHelper<K> {
    public static Validation<K> notNull = SimpleValidation.from(o -> o != null, "must not be null.");
}

同样,键入以下带有对象的验证也不会打扰我:

public abstract class GenericHelper {

    public static Validation<Object> notNull = SimpleValidation.from(o -> o != null, "must not be null.");
}

...因为在调用链中,它将产生编译错误,因为notNull的结果将是Validation <Object>,并且将期望Validation <Integer>

notNull.and(lowerThan(100)).test(toValidate).isValid(); //Does not compile

有什么方法可以使用Java 8功能特性来使该接口保持通用状态,而与我上面尝试过的解决方案背道而驰?

感激的

霍尔格:

您应该放宽的通用签名and,允许Validation<T>使用更具体的Tas参数来生成Validation<T>as结果:

default <T extends K> Validation<T> and(Validation<T> other) {
    return param -> {
        ValidationResult firstResult = this.test(param);
        return ! firstResult.isValid()? firstResult: other.test(param);
    };
}

坚持你的例子,你仍然不能写

void validate(int toValidate) {
    notNull.and(moreThan(100)).test(toValidate).isValid();
}

作为moreThan回报Validation<String>哪些不可以testint,但斑点这样的错误是什么泛型是所有关于(我想,你有另一个moreThan在您的实际代码库方法,你没有在你的问题包括)。但是以下内容现在可以与您的示例一起使用:

void validate(int toValidate) {
    notNull.and(lowerThan(100)).test(toValidate).isValid();
}

有时,您需要先测试更具体类型的验证,然后才能进行更通用的验证,而该验证仍然不适用于上述方法。一种解决方案是与JDK开发人员走同一条路线,并Function.andThen(after)添加一个Function.compose(before),以交换角色

default <T extends K> Validation<T> compose(Validation<T> other) {
    return param -> {
        ValidationResult firstResult = other.test(param);
        return ! firstResult.isValid()? firstResult: this.test(param);
    };
}

或者您创建一个static方法,该方法允许两个参数都具有比结果更大的类型Validation

static <T> Validation<T> and(Validation<? super T> first, Validation<? super T> second) {
    return param -> {
        ValidationResult firstResult = first.test(param);
        return ! firstResult.isValid()? firstResult: second.test(param);
    };
}

请注意,该static方法可以与便捷的实例方法结合使用,以便调用者仅static在遇到通用签名的限制时才诉诸该方法:

@FunctionalInterface
public interface Validation<K> {
    ValidationResult test(K item);

    default <T extends K> Validation<T> and(Validation<T> other) {
        return and(this, other);
    }
    static <T> Validation<T> and(Validation<? super T> first,Validation<? super T> second){
        return param -> {
            ValidationResult firstResult = first.test(param);
            return ! firstResult.isValid()? firstResult: second.test(param);
        };
    }
}

所以你仍然可以写

notNull.and(lowerThan(100)).test(toValidate).isValid();

但是当达到限制时,例如

Validation<Object> anotherCriteria;
…
lowerThan(100).and(anotherCriteria).test(toValidate).isValid();

不起作用,您可以求助于

Validation.and(lowerThan(100), anotherCriteria).test(toValidate).isValid();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Monad 挑战 - 一个遗漏的概括

如何将2个div左右放在一个回合上?

如何概括代码以在 WPF 应用程序中每个窗口只允许一个实例

将Axios请求概括为一个功能

概括化,haskell中的任何一个功能

将几个动作概括成一个Jquery函数

如何概括我的算法以检测一个字符串是否是另一个字符串的旋转

如何创建一个静态类的“属性”对象?

如何使用一个静态导入的方法引用?

如何创建一个静态的字符串数组?

如何创建一个包含静态库的Pod?

如何制作一个非静态的Caffe网络架构?

如何创建一个静态的整数类?

如何创建一个非静态内部Activity类?

一站式分配4个不同的玩家到一个回合

静态方法-如何从另一个方法调用一个方法?

HTML-如何使一个div可滚动,而另一个保持静态?

Swift:如何声明一个静态成员变量,它是一个类

一个非静态类如何调用另一个非静态类的方法?

如何从React中的另一个静态方法中调用一个静态方法?

在结构归纳证明中概括一个要求就可以使用归纳假设

是否可以概括一个函数并在打字稿中捕获其签名?

如何从同一个类的静态方法中调用非静态方法?

如何从另一个类的静态方法更改静态变量的值

如何动态访问另一个类的静态属性和静态常量

第一个回合后,倒数计时器中的setInterval被执行多次

使用等待通知方法在 Java 中实现一个简单的回合制游戏

开发一个静态网站

宣布一个类为静态?