2015-12-06 47 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 它可能會對你有用

相關問題