繁体   English   中英

Java参数化通用静态工厂

[英]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;

在此先感谢您的帮助。

有两件事:

  1. 您的工厂几乎肯定应该使用要实例化的 ,而不是Tool 对象 让某人创建Parser以传递到您的方法中以获取Parser有点麻烦。
  2. 我不知道是否允许通配符的方法具有通用参数; 我认为不是,因为这将是荒谬而毫无意义的。 参数化方法时,需要给通用参数起一个名称,以便以后可以引用它。

将它们放在一起,您的工厂方法可能更像这样:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM