java参数化通用静态工厂
作者:互联网
在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();
}
}
}
我想限制客户端代码只将接口’type’插入到我指定的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;
在此先感谢您的帮助.
解决方法:
有几件事:
>你的工厂几乎肯定会用一个类来实例化,而不是一个Tool对象.有人创建一个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<?扩展工具>并添加一个受保护的方法,允许其他类注册映射.
这并不是说你当前的版本不能正常工作,只是因为它不能很好地扩展,而且现在我认为它没有做太多事情来证明拥有一个单独的工厂而不是调用者只需调用toolClass.newInstance( ) 他们自己.
标签:java,factory,generics,design-patterns,factory-method 来源: https://codeday.me/bug/20191002/1842814.html