如何用Java中的泛型实现工厂模式? [英] How to implement factory pattern with generics in Java?
问题描述
我有一个通用界面处理程序
public interface Handler<T> {
void handle(T obj);
}
我可以有n个这个接口的实现。假设我现在有以下2个实现。一个处理String对象和另一个句柄的日期
I can have n implementations of this interface. Let's say I have following 2 implementations for now. One which handles String objects and another handles Date
public class StringHandler implements Handler<String> {
@Override
public void handle(String str) {
System.out.println(str);
}
}
public class DateHandler implements Handler<Date> {
@Override
public void handle(Date date) {
System.out.println(date);
}
}
我想写一个工厂,它将返回处理程序实例基于类类型。这样的事情:
I want to write a factory which will return handler instances based on the class type. Something like this :
class HandlerFactory {
public <T> Handler<T> getHandler(Class<T> clazz) {
if (clazz == String.class) return new StringHandler();
if (clazz == Date.class) return new DateHandler();
}
}
我在这家工厂遇到以下错误:
I get following error in this factory :
类型不匹配:无法从
StringHandler
转换为Handler< ; T>
Type mismatch: cannot convert from
StringHandler
toHandler<T>
如何解决此问题?
推荐答案
简单解决方案
您可以保存映射类< T> - >处理器< T>
在地图
中。类似于:
You could save your mappings Class<T> -> Handler<T>
in a Map
. Something like:
Map<Class<T>, Handler<T>> registry = new HashMap<>();
public void registerHandler(Class<T> dataType, Class<? extends Handler> handlerType) {
registry.put(dataType, handlerType);
}
public <T> Handler<T> getHandler(Class<T> clazz) {
return registry.get(clazz).newInstance();
}
在某些地方,初始化处理程序(可能在工厂本身):
In some place, initialize handlers (could be in the factory itself):
factory.registerHandler(String.class, StringHandler.class);
factory.registerHandler(Date.class, DateHandler.class);
在其他地方,您可以创建并使用它们:
And in another place, you create and use them:
Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);
更复杂的解决方案
您可以使用反射扫描类,而不是手动注册映射 Class< T> - >处理程序< T>
,使用反射执行。
You can "scan" classes using reflection and, instead of register manually the mappings Class<T> -> Handler<T>
, do it using reflection.
for (Class<? extends Handler> handlerType : getHandlerClasses()) {
Type[] implementedInterfaces = handlerType.getGenericInterfaces();
ParameterizedType eventHandlerInterface = (ParameterizedType) implementedInterfaces[0];
Type[] types = eventHandlerInterface.getActualTypeArguments();
Class dataType = (Class) types[0]; // <--String or Date, in your case
factory.registerHandler(dataType, handlerType);
}
然后,您可以像上面一样创建和使用它们:
Then, you create and use them like above:
Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);
要实现 getHandlerClasses()
,请查看此可扫描罐
。对于每个班级,您必须检查它是否是处理程序
:
To implement getHandlerClasses()
, look at this to scan all classes in your jar
. For each class, you have to check if it is a Handler
:
if (Handler.class.isAssignableFrom(scanningClazz) //implements Handler
&& scanningClazz.getName() != Handler.class.getName()) //it is not Handler.class itself
{
//is a handler!
}
希望有所帮助!
这篇关于如何用Java中的泛型实现工厂模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!