使用Guice的GoF标准工厂模式

时间:2015-01-10 00:47:36

标签: java guice factory-pattern

我之前使用标准工厂模式方法创建类的实例(实现特定接口),使用Factory类,该类具有“create”方法,该方法根据传递给它的参数返回正确的实例(例如下面给出的片段):

public class SimpleFactory {
    public static SimpleObjectInterface getSimpleObject(int data) {
         SimpleObjectInterface toReturn;
          switch(data) {
           case 1:
            toReturn = new OneSimpleObject();
           break;
          case 2:
            toReturn = new TwoSimpleObject();
          break;
          default:
             toReturn = new DefaultSimpleObject();    
          break;  
        }
        return toReturn;
      }
}

现在我在我的项目中使用Guice进行依赖注入。我的问题是如何使用Guice实现上述功能?需要哪个实现实例是在运行时根据一些用户输入决定的。

我查看过Provider和@Named注释。但我不明白它究竟会对我有多大帮助。

1 个答案:

答案 0 :(得分:2)

一般而言,对于您希望工厂注入大多数依赖项但仍允许某些客户端提供的deps的问题,您可以使用Factories by Assisted Injection

但是在你的情况下,这将导致你的工厂出现条件逻辑,这可能并不理想(在Guice模块中明确discouraged)。

我认为对于你的情况来说MapBinder是理想的,你根本不需要工厂,因为你只是打开数据类型而不是真正构建任何东西。在您的模块中,您可以配置int(在您的情况下)键的映射到SimpleObjectInterface的impl。然后在主运行时类中注入映射,当需要一个简单对象的实例并且可以使用int data时,可以在注入的映射上调用get(data)

我这台机器上没有IDE,所以我无法测试代码,但是从内存中可以看出如下所示:

在你的模块中:

public class MyModule extends AbstractModule {
  protected void configure() {
    MapBinder<Integer, SimpleObjectInterface> mapbinder
        = MapBinder.newMapBinder(binder(), Integer.class, SimpleObjectInterface.class);
    mapbinder.addBinding(1).toClass(OneSimpleObject.class);
    mapbinder.addBinding(2).toClass(TwoSimpleObject.class);
  }
}

在您的应用代码中:

@Inject
private Map<Integer, SimpleObjectInterface> simpleObjectMap;

...

void applicationCode() {
  ...
  Integer data = getData();
  SimpleObjectInterface simpleObject = simpleObjectMap.get(data);
  ...
}

这里唯一的问题是你不能拥有switch语句中的“默认”绑定。不确定处理这种情况的最佳方法,如果在尝试从地图绑定器中实例化对象后对象仍为空,则可以在应用程序代码中指定默认impl。或者你可以回到辅助注入条件逻辑,但如果唯一的依赖是客户端提供,它不是真正的“辅助”注入。

另请参阅:Can Guice automatically create instances of different classes based on a parameter?