用Guice实现参数化工厂

时间:2011-06-16 14:35:43

标签: 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 (obj) {
    case OBJECT1: return new Object1();
    case OBJECT2: return new Object2();
    ...
    }
  }

有没有简单的方法来实现它? 像Provider.get(参数)和使用绑定来定义在每种情况下应该使用哪个对象?

2 个答案:

答案 0 :(得分:6)

这里有几种选择。

1。,因为您使用enum来区分实现,那么您可以使用自己的绑定定义每个实现的有限数量,前提是您在使用期间使用注释注射

public @interface SomeInterfaceKind {
    MyObjects value();
}

Module

bind(SomeInterface.class)
    .annotatedWith(new SomeInterfaceKindImpl(MyObjects1.OBJECT1)
    .to(Object1.class);
...

然后在要注入的课程中:

@Inject void setSomeInterface(
    @SomeInterfaceKind(MyObjects.OBJECT1) SomeInterface object) {...}

在这里,您必须定义实现SomeInterfaceKindImpl的{​​{1}}类(是的,可以扩展注释!)有关更多详细信息,请查看Guice中SomeInterfaceKind的实现方式

2。您还可以使用Guice MapBinder ,如下所示(我发现它更容易实现)

在你的单元中:

Named

然后注入方法:

MapBinder.newMapBinder(MyObjects.class, SomeInterface.class)
    .addBinding(MyObjects.OBJECT1).to(Object1.class);
MapBinder.newMapBinder(MyObjects.class, SomeInterface.class)
    .addBinding(MyObjects.OBJECT2).to(Object2.class);

答案 1 :(得分:4)

您也可以使用辅助注射

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;