坚持尝试抽象的东西,我试图过度简化?

时间:2015-10-26 19:43:11

标签: java abstraction

我正在处理一堆任务,每个任务都有一些他们使用的参数。其中一些参数是必需的,其他参数是可选的,一些任务具有其他任务不具有/不会使用的参数。系统目前的构建方式,每个任务都有自己的参数类。这样的例子。 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
}}

有没有办法让我使用param类来做到这一点?我最初想过使用所有TaskParams扩展的基础参数类,但并非所有任务都使用或需要相同的参数。所以我不能baseParam.getFilePath。我看了一点反思,但如果存在更好的方法,我宁愿不去那条路。

2 个答案:

答案 0 :(得分: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" )

答案 1 :(得分: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");