java参数化通用静态工厂 [英] java parameterized generic static factory
问题描述
在Java中创建一个静态工厂方法/类是否可以使用接口作为参数化类型并返回此给定接口的实现类?
Is it possible in Java to create a static factory method/class that uses an interface as the parameterized type and return an implementing class of this given interface?
尽管我对泛型的知识是有限的,这里是我想做的:
Although my knowledge of Generics is limited, here is what I want to do:
// 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()方法中。这样我就知道插入的工具类型是一个合法的工具。
I want to restrict the client code to only insert an interface 'type' into the getInstance() method that extends from the Tool interface I specified. This way I know for sure that the tooltype that is inserted is a legitimate tool.
客户端代码应如下所示:
Client code should look like this:
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(... , ...);
}
}
工厂应该打开界面的类型粗心大意,如果它是空或不),在工厂要求之前定义。我知道这不行,我希望有一位读者知道我想完成什么。
The factory should switch on the type of the interface (careless if it's null or not), defined before it is asked from the factory. I know this is not going to work the way I wrote this, but I hope one of the readers knows what I want to accomplish.
getInstance方法的返回类型与传入参数相同,因此当传递Parser接口时,它还返回一个Parser p = new ParserImpl();返回p;
The return type of the getInstance method is the same as the incoming parameter, so when a Parser interface is passed, it also returns a Parser p = new ParserImpl(); return p;
提前感谢帮助我。
推荐答案
几件事:
- 您的工厂几乎肯定会采用类来实例化,而不是工具物体。有人创建一个
Parser
来传递你的方法,以获得一个解析器
是一个鸡和鸡蛋 - 我不知道你是否允许有通配符的方法的通用参数;我认为不是因为这将是荒谬和无意义的。当您参数化方法时,您需要给通用参数一个名称,以便稍后参考。
- Your factory should almost certainly take a class to instantiate, rather than a Tool object. Having someone create a
Parser
to pass into your method in order to get aParser
is a bit chicken-and-egg. - I don't know if you're allowed to have generic parameters for methods that are wildcards; I presume not since this would be nonsensical and pointless. When you parameterise a method, you need to give the generic parameter a name so that you can refer to it later on.
将这些参数在一起,您的工厂方法可能看起来更像:
Putting these together, your factory method might look more like this:
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()
。
If you want to restrict the type of toolClass
to be an interface, you can't do this at compile-time, but you can of course introduce a runtime check toolClass.isInterface()
.
顺便说一句,这个静态硬编码切换不是很好一般来说,在我看来,将类到构造函数的关系置于一个 Map
中,并动态地查找构造过程,甚至可以将值存储为 Callable<?extends Tool>
并添加一个允许其他类注册映射的受保护方法。
By the way, this static hardcoded switching isn't very nice in general. To my mind, it would be nicer to put the class-to-constructor relationship in a Map
and look up the construction process dynamically. Maybe even store the value as a Callable<? extends Tool>
and add a protected method allowing other classes to register mappings.
这并不是说您当前的版本不起作用,只是它不缩放非常好,现在我不认为有一个单独的工厂是合理的,而不是调用者简单地调用 toolClass.newInstance()
自己。
That's not to say that your current version doesn't work, just that it doesn't scale very well, and right now I don't think it's doing much to justify having a separate factory rather than the caller simply invoking toolClass.newInstance()
themselves.
这篇关于java参数化通用静态工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!