java - 实现通用工厂

标签 java generics factory interface-implementation

我正在尝试为可插拔接口(interface)设计一个工厂。这个想法是,一旦您拥有工厂实例,工厂就会为该特定实现返回适当的子类。

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

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

以下是我尽最大努力将情况消化为 sscce 的大量代码。 .我知道它很长,但它比看起来更简单,sscce 中的一个词是“完成”。

公共(public) API:

public interface Factory {
  public <T extends IFoo> T makeIFoo(Class<T> klass);
}

public interface IFoo {
  void doSomething();
}

public interface IFooBar extends IFoo {
  void doBarTask();
}

public interface IFooBaz extends IFoo {
  void doBazTask();
}

示例用例:

public class SomeClass {
  private Factory myFactory; 

  public void doSomething() {
    IFooBar ifb = myFactory.create(IFooBar.class);
  }
}

SSCCE 实现版本:

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);
    }
}

在工厂尝试:

这并没有指定返回将始终实现ICode。但是传入的接口(interface)类没有实现 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();
  }
}

我该怎么办?

最佳答案

我意识到我把它弄得太复杂了。如果我要为每个 enum 实例实现一个工厂方法,我还不如为每个接口(interface)使用单独的工厂方法。

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

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

当然,如果有新接口(interface),现在我必须更改 Factory API,但我希望这种情况很少见。

关于java - 实现通用工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18946860/

相关文章:

php - 工厂/抽象工厂混淆

JAVA -> EXE 包在 Windows Server 2008 中无法运行,为什么?

java - 计算程序中的变化 - 浮点错误

reactjs - 使用 [ key :string]: any to avoid needing an extra function for generics?

interface - 我应该为跨平台实现使用接口(interface)还是工厂(和接口(interface))?

c++ - 使用工厂时如何使用 "hide"构造函数?

java - 保留实体中可嵌入的列表

java - 从Java中的线程调用JMX连接?

c# - 在树层次结构中具有深度限制的通用深度克隆

generics - Kotlin 和 Mockito : Type mismatch when using vararg on the begin of the function