2013-01-14 24 views
4

我正在爲某些對象(這些對象的字段)設計驗證器。這些對象被封閉在一個更大的對象容器中。Java - 設計驗證器,類層次結構

示例:汽車作爲容器。由車輪,發動機,車身組成。 假設我需要驗證車輪是否有正確的直徑,發動機有正確的容量,車身有一定的長度等。

理論上我認爲我應該在建造集裝箱(汽車)之前驗證一切。

達到此目的的最佳方法是什麼?我是否使用validate()方法創建抽象驗證器類並在每個封閉類中實現它?怎麼樣的容器,我是否在驗證過程中根本沒有包含它?感謝幫助。

+2

同樣無效的容器可能由有效的組件構成,如果它們不匹配在一起的話,那麼您可能需要對整個容器進行嚴格的驗證。全部爲 – h22

回答

2

我建議你不要把驗證邏輯放在裏面你要驗證的類。

我發現最好把這些類保留爲值對象,並創建一個驗證器的並行層次結構,對於要驗證的每個實體大致是一個。或者,您也可以創建一個可驗證所有實體的驗證程序:但是,此解決方案的可擴展性較差,並且可能會在您必須添加新實體時違反open-closed principle(例如,查看汽車的後視鏡)。

假設您選擇one entity : one validator方法,容器驗證程序將首先驗證容器內的組件,然後驗證它們是否合在一起。

請考慮使用驗證框架的可能性,如Apache Commons Validator,它可以幫助您避免編寫樣板代碼。但是,由於我不知道您需要執行哪種複雜的驗證,因此我不知道它是否符合您的需求。

此外,我認爲你不應該擔心在構建它之前驗證所有東西。只需構建它並在之後進行驗證:那麼,如果它違反了驗證規則,則可以放棄它(即不要將它保留在任何地方)。

+1

。將類中的驗證放在SRP中。 – PositiveGuy

1

您可以使用validate方法創建ValidatablePart接口,讓所有部件實現此接口,然後讓容器驗證所有包含的部分,因爲它們被添加到容器中,或者可能在調用容器的構建或任何方法時這應該是構建它。

您的Container類可能會遵循Template Method Design Pattern

1

piggy support off gd1 answer,我同意。其中一種方法是爲每個值對象都設置一個ValidatorAdapter。因此,它應該是這樣的:

public class GreenCarValidator { 
    public GreenCarValidator(Car car) { 
     // save reference 
    } 

    @Override 
    public boolean isValid() { 
     return car.getColor().equals("green"); 
    } 
} 

public class RedCarValidator { 
    public RedCarValidator(Car car) { 
     // save reference 
    } 

    @Override 
    public boolean isValid() { 
     // you could compose more validators here for each property in the car object as needed 
     return car.getColor().equals("red"); 
    } 
} 

現在你可以有許多種驗證的單個類型的對象,動態配置在運行時的。如果你將類型爲「valid()」的類放在gd1所建議的類中,你將失去這種靈活性。