Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用Guice实现参数化工厂_Java_Design Patterns_Guice - Fatal编程技术网

Java 用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 (

我有一个工厂,我喜欢使用Guice重新实现:

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;

谢谢你的回复。据我所知,第一个选项在编译时已知实际类时更合适,而第二个选项允许在运行时决定使用哪个实现。