我在网上找到了这篇文章: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()));
看起来它将按照您的要求工作。