我在网上找到了这篇文章:https://gtrefs.github.io/code/combinator-pattern/。作者介绍了网站上要求用户输入姓名,电子邮件和年龄的用户的验证过程。如果验证过程失败,它将输出一条错误消息。

我认为,这种方法非常适合使代码易于理解。但是,他的解决方案有一个缺点。最后,此模式一次仅产生一个错误。如果名称为空,并且电子邮件中不包含@符号,则仅打印“名称为空”。

根据代码段

static UserValidtion all(UserValidation... validations){
  // Your code here
}


在本文的结尾,我尝试创建一种方法来生成这些错误的列表。

但是我想出了一个非常糟糕的解决方案,该解决方案在UserValidation接口中显示了原因。虽然如此,它会产生NullPointerException(在这里您可以执行我的代码:http://tpcg.io/WSI2u3):

UserValidation.java

static UserValidation all(UserValidation... validations){
        return user ->
        {
            Arrays.stream(validations).forEach(validation -> {
                //returns the reason  why one of the user inputs is not valid
                System.out.println(validation.apply(user).getReason());
                //I don't know how to combine the reasons here to have a proper output in the main.
            });

            return null;
        };
    }


Main.java

public class Main {

    public static void main(String[] args) {

        UserValidation rules[] = {UserValidation.nameIsNotEmpty(),UserValidation.eMailContainsAtSign()};
        UserValidation validation = UserValidation.all(rules);
        User gregor = new User("", 30, "mailmailinator.com");
        ValidationResult result = validation.apply(gregor);
        result.getReason().ifPresent(System.out::println);

    }
}


我对lambda表达式不甚了解,但我尝试了很多,但不适合这种方法。
这是我尝试的:


在接口UserValidation中添加了一个静态ArrayList来保存传递的原因。无法工作,因为主方法中的调用仅接受UserValidation-Object。
在接口ValidationResult中添加了一个ArrayList来存储原因列表。也没有用,因为我无法一次访问所有原因。


提前致谢。

最佳答案

我在您的代码中做了几处更改

    static Function< User, List<ValidationResult> > all(UserValidation... validations){
    return user ->
    {
        return Arrays.stream(validations).map(validation ->
            validation.apply(user)
        ).filter(vr-> !vr.isValid())
        .collect(Collectors.toList());

    };
}


并更改了主要内容以显示验证错误。

        UserValidation rules[] = {UserValidation.nameIsNotEmpty(),UserValidation.eMailContainsAtSign()};
    Function< User, List<ValidationResult> > validation = UserValidation.all(rules);
    User gregor = new User("", 30, "mailmailinator.com");
    List<ValidationResult> result = validation.apply(gregor);

    result.forEach(item -> System.out.println(item.getReason().get()));


看起来它将按照您的要求工作。

07-24 18:12