具有验证器继承的Fluent API - 输入验证器实例似乎被标识为父类

时间:2017-07-12 22:36:00

标签: java fluent-interface

我正在编写一个流畅的API来验证地图中的key:value对。我有一个验证器类型的层次结构。我提到了Fluent API with inheritance and generics的一个答案。

public interface IValidator {
    IValidator assertValue(String key, String expectedValue) throws Exception;

    abstract class Abstract implements IValidator {

        protected final Map<String, String> resultMap = new HashMap<>();

        @Override
        public <T extends IValidator> T assertValue(String key, String expectedValue) throws Exception {
            ...
            return (T) this;
    }
}

第二级抽象子类重新定义父类型,如下所示。

public abstract class AbstractValidator
extends IValidator.Abstract {
    // other logic not related to assertion
}

具体子类同样重新定义父类型。

public class ExampleValidator
extends AbstractValidator
{
    public ExampleValidator assertPromptId(String expectedValue) throws Exception{
        assertValue(PROMPT_ID, expectedValue);
        return  this;
    }

    public ExampleValidator assertNameSpace(String expectedValue ) throws Exception{
        assertValue(NAMESPACE, expectedValue);
        return this;
    }

    @Override
    public ExampleValidator assertValue(String key, String  expectedVlaue) throws Exception {
        super.assertValue(key, expectedVlaue);
        return this;
    }

现在,我的测试用例如下。我的问题是.withValidator(Ivalidator validator)无法找到assertPromptId()assertNameSpace()的方法,只能找到assertValue()的方法。那么如何解决呢?

public class AssertionContext {
    public <T extends IValidator> T withValidator(IValidator validator) throws Exception {
        return (T) validator;
    }
} 

// test method in main
public void invocationTest() throws Throwable {
        AssertionContext verify = new AssertionContext();
        verify.withValidator(new ExampleValidator()).assertNameSpace("...");
    }

1 个答案:

答案 0 :(得分:1)

实际上我发现解决方案很简单。

public <T extends IValidator> T withValidator(T t) throws Exception {
    ...
    return t;
}