Java 用Guice实现参数化工厂
我有一个工厂,我喜欢使用Guice重新实现:Java 用Guice实现参数化工厂,java,design-patterns,guice,Java,Design Patterns,Guice,我有一个工厂,我喜欢使用Guice重新实现: enum MyObjects { OBJECT1, OBJECT2, ... } class Object1 implements SomeInterface { ... } class Object2 implements SomeInterface { ... } ... class Factory { public static SomeInterface createObject(MyObjects obj) { switch (
enum MyObjects { OBJECT1, OBJECT2, ... }
class Object1 implements SomeInterface { ... }
class Object2 implements SomeInterface { ... }
...
class Factory {
public static SomeInterface createObject(MyObjects obj) {
switch (obj) {
case OBJECT1: return new Object1();
case OBJECT2: return new Object2();
...
}
}
有没有一个简单的方法来实现它?
类似于Provider.get(参数)和使用绑定来定义在每种情况下应该使用哪个对象?这里有几个选项 1。由于您使用
enum
来区分实现,因此您可以使用有限数量的实现来定义每个实现及其各自的绑定,前提是您在注入期间使用注释
public @interface SomeInterfaceKind {
MyObjects value();
}
在模块中
:
bind(SomeInterface.class)
.annotatedWith(new SomeInterfaceKindImpl(MyObjects1.OBJECT1)
.to(Object1.class);
...
然后在要注入的类中:
@Inject void setSomeInterface(
@SomeInterfaceKind(MyObjects.OBJECT1) SomeInterface object) {...}
这里您必须定义实现SomeInterfaceKind
的SomeInterfaceKind
类(是的,可以扩展注释!)有关更多详细信息,请查看如何在Guice中实现命名的
2.您还可以使用GuiceMapBinder如下(我发现它更容易实现)
在您的模块中:
MapBinder.newMapBinder(MyObjects.class, SomeInterface.class)
.addBinding(MyObjects.OBJECT1).to(Object1.class);
MapBinder.newMapBinder(MyObjects.class, SomeInterface.class)
.addBinding(MyObjects.OBJECT2).to(Object2.class);
然后在注入方法中:
@Inject void setSomeInterface(Map<MyObjects, SomeInterface> map) {
SomeInterface object1 = map.get(MyObjects.OBJECT1);
...
}
@Injectvoid setSomeInterface(映射){
SomeInterface object1=map.get(MyObjects.object1);
...
}
您也可以使用辅助注入
public interface Factory {
public Object1 createObject1(String param1);
public Object2 createObject2(Date param2);
}
public class Object1 {
@AssistedInject
public Object1(String param1) {
// do something
}
}
public class Object2 {
@AssistedInject
public Object2(Dateparam2) {
// do something
}
}
然后在你的模块中
install(new FactoryModuleBuilder()
.implement(Object1.class, Object1.class)
.implement(Object2.class, Object2.class)
.build(Factory.class));
然后你可以在任何你需要的地方使用工厂
@Inject
private Factory factory;
谢谢你的回复。据我所知,第一个选项在编译时已知实际类时更合适,而第二个选项允许在运行时决定使用哪个实现。