Java 实现通用工厂

Java 实现通用工厂,java,generics,factory,interface-implementation,Java,Generics,Factory,Interface Implementation,我正在尝试为可插拔接口设计一个工厂。其思想是,一旦有了工厂实例,工厂将返回该特定实现的适当子类 在本例中,我包装了一个第三方库,它使用字符串来表示ID代码,而不是子类。因此,在封装其库的实现中,每个实现类都有一个接口API不明确要求的方法getCode()。我使用enum来存储代码和接口类之间的映射 几乎在所有情况下,都不需要getCode()方法。但是,在实现包中的一些情况下,我需要访问该方法。因此,我的问题是我希望让工厂实现的签名告诉调用方getCode方法存在,如果它们引用了特定的工厂实现

我正在尝试为可插拔接口设计一个工厂。其思想是,一旦有了工厂实例,工厂将返回该特定实现的适当子类

在本例中,我包装了一个第三方库,它使用字符串来表示ID代码,而不是子类。因此,在封装其库的实现中,每个实现类都有一个接口API不明确要求的方法
getCode()
。我使用
enum
来存储代码和接口类之间的映射

几乎在所有情况下,都不需要
getCode()
方法。但是,在实现包中的一些情况下,我需要访问该方法。因此,我的问题是我希望让工厂实现的签名告诉调用方
getCode
方法存在,如果它们引用了特定的工厂实现

下面是大量代码,我尽了最大努力试图将这种情况消化成一个简单的例子。我知道它很长,但它比看起来更简单,sscce中的一个词是“完整”

公共空气污染指数: SSCCE实施版本: 枚举代码映射器: 在工厂的尝试: 这并没有指定返回将始终实现
ICode
。但是传入的接口类没有实现
ICode
,这就是关键所在

class CodeFactory implements Factory {
  @Override
  public <T extends IFoo> T makeIFoo(Class<T> klass) {
    CodeMap map = CodeMap.getFromClass(klass);

    if (map == null) return null; // Or throw an exception, whatever, SSCCE

    return (T) map.create();
  }
}
类CodeFactory实现工厂{
@凌驾
公共T makeIFoo(klass类){
CodeMap-map=CodeMap.getFromClass(klass);
if(map==null)返回null;//或者抛出异常,不管怎样,SSCCE
return(T)map.create();
}
}

我该怎么办?

一个可能的解决方案是定义一个实现
IFoo
getCode()
方法的包装器,您的方法将在其中一个包装器中返回所需的类


如果包装的实例实现了一个
getCode
,包装器将返回其值,否则返回
null

我意识到这太复杂了。如果我要为每个
enum
实例实现一个工厂方法,我还可以为每个接口使用单独的工厂方法

public interface Factory {
    IFooBar createFooBar();
    IFooBaz createFooBaz();
}

class CodeFactory implements Factory {
    public FooBarImpl createFooBar() {
        // etc.
    }
}

当然,如果有新的接口,我现在必须更改工厂API,但我希望这将是罕见的。

正如我在回答中所解释的,我认为您所做的不是工厂,因为使用实例的代码是决定实例化哪个类的代码(因此,没有解耦)。无论如何,为了避免长时间的讨论,我将删除我的答案,因为它不能让您信服。@PaulBellora您说得很好,但这是枚举中定义的包私有方法。但是你已经指出了SSCCE翻译中的一个错误,我会改正的now@SJuan76实现类都是包私有的。方法调用是
factory.makeClass(子接口)
not
factory.makeClass(具体类)
interface ICode {
  String getCode();
}

abstract class BaseCode implements IFoo, ICode {
  private String code;

  BaseCode(String code) {
    this.code = code;
  }

  @Override
  public String getCode() {
    return code;
  }

  @Override
  public void doSomething() {
    System.out.println("Something");
  }
}

class FooBarImpl extends BaseCode implements ICode, IFooBar {
  FooBarImpl(String code) {
    super(code);
  }

  @Override
  public void doBarTask() {
    System.out.println("BarTask");
  }
}

class FooBazImpl extends BaseCode implements ICode, IFooBaz {
  FooBazImpl(String code) {
    super(code);
  }

  @Override
  public void doBazTask() {
    System.out.println("BarTask");
  }
}
static enum CodeMap {
  FOOBAR ("A", IFooBar.class) {
    FooBarImpl create() { return new FooBarImpl(getCode()); }
  },
  FOOBAZ ("B", IFooBaz.class) {
    FooBazImpl create() { return new FooBazImpl(getCode()); }
  };

  private static Map<Class<? extends IFoo>, CodeMap> classMap;
  static {
    classMap = new HashMap<Class<? extends IFoo>, CodeMap>();
    for(CodeMap cm : CodeMap.values()) {
      classMap.put(cm.getFooClass(), cm);
    }
  }

  private String code;
  private Class<? extends IFoo> klass;

  private CodeMap(String code, Class<? extends IFoo> klass) {
    this.code = code;
    this.klass = klass;
  }

  String getCode() {
    return code;
  }

  Class<? extends IFoo> getFooClass() {
    return klass;
  }

  static CodeMap getFromClass(Class<? extends IFoo> klass) {
    return classMap.get(klass);
  }

  abstract BaseCode create();
}
public class InternalClass {
    CodeFactory factory;

    public void doSomething() {
        FooBarImpl fb = factory.makeIFoo(IFooBar.class);
    }
}
class CodeFactory implements Factory {
  @Override
  public <T extends IFoo> T makeIFoo(Class<T> klass) {
    CodeMap map = CodeMap.getFromClass(klass);

    if (map == null) return null; // Or throw an exception, whatever, SSCCE

    return (T) map.create();
  }
}
public interface Factory {
    IFooBar createFooBar();
    IFooBaz createFooBaz();
}

class CodeFactory implements Factory {
    public FooBarImpl createFooBar() {
        // etc.
    }
}