[英]java parameterized generic static factory
在Java中是否可以创建将接口用作参数化类型的静态工厂方法/类,并返回此给定接口的实现类?
尽管我对泛型的了解有限,但是我想做的是:
// define a base interface:
public interface Tool {
// nothing here, just the interface.
}
// define a parser tool:
public interface Parser extends Tool {
public ParseObject parse(InputStream is);
}
// define a converter tool:
public interface Converter extends Tool {
public ConvertObject convert(InputStream is, OutputStream os);
}
// define a factory class
public class ToolFactory {
public static <? extends Tool> getInstance(<? extends Tool> tool) {
// what I want this method to return is:
// - ParserImpl class, or
// - ConverterImpl class
// according to the specified interface.
if (tool instanceof Parser) {
return new ParserImpl();
}
if (tool instanceof Converter) {
return new ConverterImpl();
}
}
}
我想限制客户端代码,使其仅将接口“类型”插入从我指定的Tool接口扩展的getInstance()方法中。 这样,我可以确定插入的工具类型是合法工具。
客户端代码应如下所示:
public class App {
public void main(String[] args) {
Parser parser = null;
Converter converter = null;
// ask for a parser implementation (without knowing the implementing class)
parser = ToolFactory.getInstance(parser);
// ask for a converter implementation
converter = ToolFactory.getInstance(converter);
parser.parse(...);
converter.convert(... , ...);
}
}
工厂应在询问工厂之前打开定义的接口类型(粗心的是否为空)。 我知道这不会像我写这篇文章那样起作用,但是我希望其中一位读者知道我想要完成的工作。
getInstance方法的返回类型与传入参数相同,因此当传递Parser接口时,它还返回Parser p = new ParserImpl();。 返回p;
在此先感谢您的帮助。
有两件事:
Parser
以传递到您的方法中以获取Parser
有点麻烦。 将它们放在一起,您的工厂方法可能更像这样:
public static <T extends Tool> T getInstance(Class<T> toolClass) {
if (Parser.class.isAssignableFrom(toolClass) {
return new ParserImpl();
}
else if (Converter.class.isAssignableFrom(toolClass) {
return new ConverterImpl();
}
// You'll always need to have a catch-all case else the compiler will complain
throw new IllegalArgumentException("Unknown class: " + toolClass.getName());
}
如果要限制toolClass
的类型为接口,则不能在编译时执行此操作,但是当然可以引入运行时检查toolClass.isInterface()
。
顺便说一句,这种静态硬编码的切换通常不太好 。 在我看来,将类与构造函数的关系放在Map
并动态查找构造过程会更好。 甚至将值存储为Callable<? extends Tool>
Callable<? extends Tool>
并添加了一个受保护的方法,该方法允许其他类注册映射。
这并不是说您当前的版本无法正常工作,只是它的扩展性不够好,而且现在我认为它并不能证明拥有一个单独的工厂,而不是调用方仅调用toolClass.newInstance()
自己。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.