我有一个Validator
它提供了一个接口isValid(Thing)
方法,返回一个ValidationResult
其中包含一个boolean
和一个原因消息。
我想创建一个ValidatorAggregator
该接口执行一个或多个的实施Validator
S(如果有的话Validator
返回一个积极的结果,那么结果是肯定的)。如果有任何验证成功,我想短路,就回到它的结果。如果没有验证成功,我想回到所有失败的消息。
我可以做到这一点简洁使用流findFirst().orElse(...)
,但使用这种模式我失去了所有的中间结果,如果findFirst
返回空:
public ValidationResult isValid(final Thing thing) {
return validators.stream()
.map(v -> validator.isValid(thing))
.filter(ValidationResult::isValid)
.findFirst()
.orElseGet(() -> new ValidationResult(false, "All validators failed'));
}
有什么办法来捕获失败的结果使用流,甚至小于下面只是更加简洁?
public ValidationResult isValid(final Thing thing) {
final Set<ValidationResult> failedResults = new HashSet<>();
for (Validator validator : validators) {
final ValidationResult result = validator.isValid(thing);
if (result.isValid()) {
return result;
}
failedResults.add(result);
}
return new ValidationResult(false, "No successful validator: " + failedResults);
// (assume failedResults stringifies nicely)
}
编辑:根据意见,我同意我想要做的是不成熟的优化(尤其是当这些验证程序是非常轻巧)。我可能会用类似于计算所有验证,并划分为成功/失败的结果霍尔格的解决方案去的东西。
这被标记为愚弄的人你能拆分流分成两个流?和partitioningBy
答案排序是的,但我认为这个问题是问,并讨论应答,不同的问题。
存在一个处理以同样的效率所有的情况下没有完美的解决方案。即使你的循环变体,其满足的是短路和处理验证只有一次的标准,有创造和填补这一可能变成只要有一个验证成功是不必要的集合的缺点。
选择取决于与运营,并具有至少一个验证成功的可能性相关联的实际成本。如果一般情况下得到最好的性能处理,就可能超过上罕见的案件的处理解决方案的处罚。
所以
// you may use this if the likelihood of a success is high; assumes
// reasonable costs for the validation and consists (repeatable) results
public ValidationResult isValid(final Thing thing) {
return validators.stream()
.map(v -> v.isValid(thing))
.filter(ValidationResult::isValid)
.findFirst()
.orElseGet(() -> new ValidationResult(false, "All validators failed"
+ validators.stream().map(v -> v.isValid(thing)).collect(Collectors.toSet())));
}
// you may use this if the likelihood of a success is
// very low and/or you intent to utilize parallel processing
public ValidationResult isValid(final Thing thing) {
Map<Boolean,Set<ValidationResult>> results = validators.stream()
.map(v -> v.isValid(thing))
.collect(Collectors.partitioningBy(ValidationResult::isValid, Collectors.toSet()));
return results.get(true).stream().findAny()
.orElseGet(() -> new ValidationResult(false,
"No successful validator: "+results.get(false)));
}
// if chances of successful validation are mixed or unpredictable
// or validation is so expensive that everything else doesn't matter
// stay with the loop
public ValidationResult isValid(final Thing thing) {
final Set<ValidationResult> failedResults = new HashSet<>();
for (Validator validator : validators) {
final ValidationResult result = validator.isValid(thing);
if (result.isValid()) {
return result;
}
failedResults.add(result);
}
return new ValidationResult(false, "No successful validator: " + failedResults);
}
考虑列表进行排序,使之与成功的机会较高验证程序是在一开始...
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句