自定义扩展点的最佳实现是什么?

时间:2016-07-07 16:15:54

标签: java validation oop design-patterns

我需要在java中为自定义验证规则制作扩展点。你能帮我找到最好的方法吗?

我的代码看起来像这样

...
public myClass() {
...
//some business logic
customValidator.validate(event); //custom validator
...
}

我知道使用基本Validator接口并使用自定义验证器实现它是合适的。

   interface Validator {
   public static Boolean validate();
   }
   public class TrueValidator implements Validator {
   public static Boolean validate() { return true;}
   }

   public class TrueValidator implements Validator {
   public static Boolean validate() { return false;}
   }

我想知道根据某些String变量调用验证的最佳模式是什么。使用Reflection API获取课程是否可以?我将从数据库中获取String,创建Class并创建它的实例。

我知道的另一个解决方案是让Validator出厂并通过Validator变量获取String,但我认为它太过分了。

你能推荐我一些想法吗?

1 个答案:

答案 0 :(得分:1)

您基本上想要基于字符串实例化验证器?有多种可能的实现,我不能告诉哪一个是最好的,但是你选择的实现应该在工厂中抽象出来。您不希望代码中充斥着逻辑,以便从字符串中查找并实例化这些验证器。

E.g。

public interface Validator {
    public boolean validate(ThingToValidate thingToValidate);
}

public final class TrueValidator implements Validator {
    //Note that the method is not static
    public boolean validate(ThingToValidate thingToValidate) {
        return true;
    }
}

public interface ValidatorFactory {
    public Validator createFromType(String type);
}

//Concrete validation factory using reflection
public final class ReflectiveValidatorFactory implements ValidatorFactory {
    public Validator createFromType(String type) {
        /*Use reflection to resolve the class based on the interface
        and naming conventions and/or annotations. 
        You may also cache the validator to avoid re-resolving it.*/
    }
}

//Concrete validation factory where validator types are hard-coded.
public final class HardcodedValidatorFactory implements ValidatorFactory {
    public Validator createFromType(String type) {
        switch (type) {
            case 'True': return new TrueValidator();
            //...
        }
    }
}

//Example of a client class that would use the ValidatorFactory
public final class ValidationService {
    private final ValidatorFactory validatorFactory;

    public ValidationService(ValidatorFactory validatorFactory) {
        this.validatorFactory = validatorFactory;
    }

    public boolean validate(String validatorType, ThingToValidate thingToValidate) {
        Validator validator = validatorFactory.createFromType(validatorType);

        return validator.validate(thingToValidate);
    }
}

请注意,您的Valiator.validate方法不应该是静态的!我知道,由于验证器是无状态的,你可能想重新使用相同的实例,因此想法使validate方法保持静态,但这样做会使你的设计灵活性和可测试性降低。

如果您希望确保重用相同的验证程序实例,那么您可以确保在Composition Root中只实例化了一个具体的ValidatorFactory,并且该工厂会缓存验证程序。 / p>