2015-12-06 46 views
1

我是编程新手。我有一个我想验证的对象列表(不是短路,而是每个都运行一个验证规则列表)。在java中验证对象的最佳方法

最初我有一个巨大的if/else语句,但它看起来并不漂亮。我认为这样会更好:

foreach (object: objects) { 
    foreach (rule: validationRules) { 
    try { 
     rule.validate(object) 
    } catch { 
     // Write to log 
     // Increment counter for rule 
    } 
    } 
} 

我只是不知道如何去创建验证规则。我想使用Java 8谓词,因为我听说这是我应该使用的,但我不知道如何去做。我想我可能会创建一个与规则的接口,然后是定义了每个规则的实现以及规则列表。这听起来像是解决这个问题的好方法吗?

谢谢!

回答

0

你的for循环是一个非常好的主意。

谓词思想取决于这是否是一种有效的方式来通过验证来做任何你想要的。我通常建议人们在开始问题之前不要将自己锁定在某个“必须使用X”的思维方式上。计划使用最简单和/或最有效的方法,但专注于特定功能会导致一种“试图用锤子敲打”的心态。

谓词不需要循环,但我认为它不是一个很好的性能选择,因为它们会创建新的对象集合,如果使用它们进行过滤,这是一个潜在的昂贵操作。一个简单的规则是一种方法(如您自己的草图所示)似乎更简单,无论是在概念上还是作为代码维护。

+0

有没有更好的方式来编写这个循环使用Java 8风格的函数式编程? –

+0

我有点老派,经验教我,代码需要清晰和简单([KISS原则](https://en.wikipedia.org/wiki/KISS_principle))。这有助于可维护性和错误修复。所以我认为你的直接循环和规则方法是一个更好的选择。我认为任何其他方法都不会更有效率。 – StephenG

+0

太棒了,那我就去吧。谢谢! –

0

我认为你可以使用Predicate来实现你的规则。由于Predicate是一种单一的抽象方法,因此可以使用简单的lambda来实现它,并且您的验证器可以使用Predicate的列表进行初始化。

public final class Validator { 
    private final List<Predicate<MyObject>> rules; 
    public final Validator(List<Predicate<MyObject>> rules) { 
     this.rules = rules; 
    } 

    public final validate(MyObject object) { 
     return rules.stream() 
        .map(Predicate::test) 
        .findAny(Boolean.FALSE).isPresent(); 
    } 
} 

而且你可以用任何你需要的lambda作为初始化类。

接下来的问题是您是否希望从多个故障中收集故障,将它们汇总在一起,或者仅仅是在第一次故障时停下来。根据你的情况,有很多选择。您可以使用异常,或者可以传递某种故障收集器。

+0

谢谢!我想通过记录它们,然后递增计数器来报告多次失败。有没有比另一个更好的方法来做到这一点? –

+0

我打算使用简单的循环,因为它看起来会做我想做的事情,并且很好而且可读。我会尽快答复你的答案,但我还没有足够的声望! –

0

我正在考虑使用谓词来验证项目中的对象,并且我遇到了这个美妙的链接https://gtrefs.github.io/code/combinator-pattern/。 基本上, 紧跟着教程后,我交换了我编写的代码的很多部分。首先,正确使用谓词使SRP突出,这绝对是前进的方式。我已经写了一个简单的验证器使用谓词的对象,并发表它在https://github.com/Raveesh/QuickProgramsForFun/tree/master/javaValidators 它可能会对你有用

相关问题