2015-10-26 86 views
1

我正在處理一堆任務,每個任務都有一些他們使用的參數。其中一些參數是必需的,其他參數是可選的,並且一些任務具有其他任務不會使用的參數。系統當前構建的方式,每個任務都有自己的參數類。所以例子。 FileIngestionTask.java有一個FileIngestionTaskParams.java卡住試圖抽象的東西,我試圖過度簡化?

現在大概有6個任務,但未來肯定會有更多的添加,所以我試圖製作一個通用的ParamValidator。 任務嘗試執行之前,我必須跑X檢查,像數...

if (FileInjestionTaskParams.getFilePath() == null){ 
    logError(X) 

但後來另一項任務,我需要覈實

if (UpdateShippingFileParams.getFilePath() == null){ 
    logError(X) 

在此之前,系統切換到一組參數類(每個任務),我們用的是map(String, Object),所以我有一個通用的參數驗證,每個班也只是setRequired(FILE_PATH)和參數驗證我可以做類似

if (required(FILE_PATH)){ 
    if (Map.get(FILE_PATH) == null) { 
     log error 
}} 

有沒有什麼辦法讓我使用參數類來做到這一點?我原本以爲使用基本參數類,所有TaskParams擴展,但並非所有任務使用或需要相同的參數。所以我不能只有baseParam.getFilePath。我對Reflection有點看,但如果存在更好的方法,我寧願不沿着這條路線走下去。

+0

讓每個參數類包括用於驗證它作爲適當的用於該特定參數'驗證()'方法? – RealSkeptic

+0

是的,但仍然涉及到我在每個參數類中寫入它。它們在技術上只是數據對象,它們是否應負責驗證其參數? – Lencalot

+1

我會讓那些params類實現一個通用接口,就像'class FileIngestionTaskParams實現FileParams'一樣。然後在驗證器中,使用'instanceof'檢查params對象,並在if塊內部進行轉換。不需要反射。 – VGR

回答

0

在java 8中,我們可以做這樣的事情。

public class FooParam 
{ 
    public String filePath(){ ... } 
    public Long fileSize(){ ... } 

-- 

public class FooTask 
{ 
    public void setValidators(Validator<FooParam>... validators){ ... 

-- 

    fooTask.setValidators(
     Validator.requires (FooParam::filePath), 
     Validator.greaterThan(FooParam::fileSize, 1024) 
     ... 
    ); 

-- 

public interface Validator<T> 
{ 
    public void validate(T t) throws Exception; 

    public static <T> Validator<T> requires(Function<T,?> prop) 
    { 
     return t-> 
     { 
      if(prop.apply(t)==null) 
       throw new Exception(); 
     }; 
    } 
    public static <T> Validator<T> greaterThan(Function<T,Long> prop, long value) 
    ... 

基本思想是使用方法引用而不是屬性名稱。

更多的東西一般是有幫助的太

Validator.of(p->p.fileSize()>1024, "file too small") 
0

另一種可能的解決方案是,如果你是從字面上談論像命令行選項選項,然後Apache Commons CLI有你解決這個問題。

// create Options object 
Options options = new Options(); 

// add t option 
options.addOption("t", false, "display current time"); 

Option logfile = OptionBuilder.withArgName("file") 
           .hasArg() 
           .withDescription( "use given file for log") 
           .create("logfile"); 

Option logger = OptionBuilder.withArgName("classname") 
           .hasArg() 
           .withDescription("the class which it to perform " 
                + "logging") 
           .create("logger"); 

Option listener = OptionBuilder.withArgName("classname") 
           .hasArg() 
           .withDescription("add an instance of class as " 
                + "a project listener") 
           .create("listener"); 

等等