当前位置:  开发笔记 > 编程语言 > 正文

如何用Java中的泛型实现工厂模式?

如何解决《如何用Java中的泛型实现工厂模式?》经验,为你挑选了1个好方法。

我有一个通用接口处理程序

public interface Handler {
  void handle(T obj);
}

我可以有这个接口的n个实现.假设我现在有以下2个实现.一个处理String对象,另一个处理Date

public class StringHandler implements Handler {
  @Override
  public void handle(String str) {
    System.out.println(str);
  }
}

public class DateHandler implements Handler {
  @Override
  public void handle(Date date) {
    System.out.println(date);
  }
}

我想编写一个工厂,它将根据类类型返回处理程序实例.像这样的东西:

class HandlerFactory {
  public  Handler getHandler(Class clazz) {
    if (clazz == String.class) return new StringHandler();
    if (clazz == Date.class) return new DateHandler();
  }
}

我在这个工厂得到以下错误:

类型不匹配:无法转换StringHandlerHandler

如何解决这个问题?



1> Héctor..:

简单的解决方案

你可以节省您的映射Class -> HandlerMap.就像是:

Map, Handler> registry = new HashMap<>();

public void registerHandler(Class dataType, Class handlerType) {
    registry.put(dataType, handlerType);
}

public  Handler getHandler(Class clazz) {
  return registry.get(clazz).newInstance();
}

在某些地方,初始化处理程序(可能在工厂本身):

factory.registerHandler(String.class, StringHandler.class);
factory.registerHandler(Date.class, DateHandler.class);

在另一个地方,您创建并使用它们:

Handler stringhandler = factory.getHandler(String.class);
Handler dateHandler = factory.getHandler(Date.class);

更复杂的解决方案

您可以使用反射"扫描"类,而不是手动注册映射Class -> Handler,使用反射进行操作.

for (Class 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);
}

然后,您可以像上面一样创建和使用它们:

Handler stringhandler = factory.getHandler(String.class);
Handler dateHandler = factory.getHandler(Date.class);

要实现getHandlerClasses(),请查看此内容以扫描您的所有类jar.对于每个班级,您必须检查它是否是Handler:

if (Handler.class.isAssignableFrom(scanningClazz) //implements Handler
    && scanningClazz.getName() != Handler.class.getName()) //it is not Handler.class itself
{
        //is a handler!
}

希望能帮助到你!

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有