我正在尝试为可插拔接口(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/