java - 工厂返回通用接口(interface)

标签 java generics factory

我有一个TemplateEngine其实现为 MoustacheTemplateEngine 的接口(interface), FreemarkerTemplateEngine等等

public interface TemplateEngine<T> {
    public T compileTemplate(String templateStr);
    public void merge(T t, Map<String, Object> data);
    public String getTemplateLang();
}

compileTemplate的目的方法是启用已编译模板的缓存。

这是一个实现示例:

import com.github.mustachejava.Mustache;

public class MoustacheTemplateEngine implements TemplateEngine<Mustache> {

    @Override
    public Mustache compileTemplate(String templateStr) {
        // return compiled template;
    }

    @Override
    public void merge(Mustache compiledTemplate, Map<String, Object> data) {
        // merge
    }

    @Override
    public String getTemplateLang() {
        return "moustache";
    }
}

我希望创建一个返回 TemplateEngine 的工厂取决于提供的模板语言。 工厂以及使用工厂的客户对TemplateEngine一无所知实现

public class TemplateEngineFactory {

    private Map<String, TemplateEngine<?>> TEMPLATE_ENGINE_REGISTRY = new HashMap<>();

    @PostConstruct
    public void init() {
        // Scan all TemplateEngine impls in classpath and populate registry
    }

    public TemplateEngine<?> getTemplateEngine(String templateLang) {
        return TEMPLATE_ENGINE_REGISTRY.get(templateLang);
    }

}

客户将按如下方式使用工厂。

Map<String, Object> data = new HashMap<>();
data.put("name", "Tom");
TemplateEngine<?> templateEngine = factory.getTemplateEngine("moustache");
Object compiledTemplate = templateEngine.compileTemplate("Hi {{name}}");
templaeEngine.merge(compiledTemplate, data); // compile error

错误为The method merge(capture#3-of ?, Map<String,Object>) in the type TemplateEngine<capture#3-of ?> is not applicable for the arguments (Object, Map<String,Object>) .

我理解该错误,并且我知道由于在工厂中使用通配符,我的 API 设计存在缺陷。我的问题是如何为此类用例设计工厂并避免不安全的强制转换?

最佳答案

您需要在某个时刻进行不安全转换。最好的选择是,

public <T> TemplateEngine<T> getTemplateEngine(String templateLang) {
    return (TemplateEngine<T>) TEMPLATE_ENGINE_REGISTRY.get(templateLang);
}

然后你可以这样调用它,

TemplateEngine<Mustache> templateEngine = factory.getTemplateEngine("moustache");

关于java - 工厂返回通用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48302584/

相关文章:

java.io.FileInputStream,未找到源

java - springboot读取tomcat-context.xml

java - 如果调用通用静态方法,编译器如何使用通用信息?

scala - 奇怪的 Scala 'Type mismatch' 元组错误

C# 从匿名类型中选择字符串列表

angularjs - 不同模块之间共享工厂值

java - 我如何为子类使用相同的工厂方法?

java - 解析字符串数组并选择特定节点值

java - java中Bencode字符串长度

ruby-on-rails - 返回 Angular 中 Rails API 的搜索结果