能为我创造一个工厂吗?

时间:2012-03-29 12:09:22

标签: java guice factory

我有以下工厂类:

public class MessagePresenterCreator implements IPresenterFactory{
    @Override
    public MessagePresenter createPresenter(Message m) {
        if (m instanceof Letter) {
            return new LetterPresenter();
        }
        if (m instanceof Cable) {
            return new CablePresenter();
        }
        if (m instanceof Postcard) {
            return new PostcardPresenter();
        }
        throw new IllegalArgumentException();
    }
}

我可以通过以下界面配置guice以自动生成并提供此类工厂:

public interface IPresenterFactory {
    public abstract MessagePresenter createPresenter(Message m);
}

2 个答案:

答案 0 :(得分:4)

我喜欢以两种方式来考虑工厂 - 仅仅从组件中组装对象的工厂,以及在该组件中进行条件逻辑的工厂。

你的工厂背后有逻辑。 Guice无法自动化该逻辑,因为它只是处理依赖关系的连接。如果您创建的类型需要一些注入的依赖项,并且只是在创建时提供了一些内容,那么工厂的自动连接可以使用guice的AssistedInject extension来完成。这将允许您提供工厂接口,使用@AssistedInject注释所创建类型中的任何字段,并且guice的扩展将创建一个工厂实现类,它将注入Injector中绑定的任何内容,并且还会传递这些create()参数。但是在这种情况下,所有Guice和AssistedInject正在做的就是将各个部分拉在一起 - 根据事先指定的配方进行连接。它不会在最后一刻做出关于它们的决定。

您正在提供对象的条件创建。那不行。

An idea above提到制作一个依赖于类型映射到演示者的工厂 - 例如:

Map<Class<? extends Message>, Class<? extends MessagePresenter>> 

如果您将其与Multibinder的MapBindings结合使用,这是一种很好的方法。 (我得加强那些文档...嗯)

使用这种方法,您可以创建一个可扩展的工厂 - 定义Message的初始映射 - &gt; MessagePresenter子类,但在以后可以打开其他映射的可能性,而无需更改工厂 - 只需在multibinder上绑定更多映射,如下所示:

 MapBinder<String, Snack> mapbinder = MapBinder.newMapBinder(
     binder(), 
     new TypeLiteral<Class<? extends Message>>(){}, 
     new TypeLiteral<Class<? extends MessagePresenter>>(){});
 mapbinder.addBinding(MyMessage.class).toInstance(MyMessagePresenter.class);
 mapbinder.addBinding(YourMessage.class).toInstance(YourMessagePresenter.class);

您可以在任意数量的模块中执行此操作,使用映射添加更多类型以进行切换。

答案 1 :(得分:1)

没有guice没有像这样的工厂。你可以写一个工厂,用Map<Class<? extends Message>, Class<? extends MessagePresenter>并使用反射。这样,如果这是您的目标,您可以在guice模块中进行管理。

public class MessagePresenterCreator implements IPresenterFactory{
    private final Map<Class<? extends Message>, Class<? extends MessagePresenter> mapping;
    public MessagePresenterCreator(Map<Class<? extends Message>, Class<? extends MessagePresenter> mapping) {
         this.mapping = mapping;
    }

    @Override
    public MessagePresenter createPresenter(Message m) {
       Class<? extends MessagePresenter> clazz = mapping.get(m);
       if (clazz == null) {
           throw new UnsupportedOperationException();
       }
       return clazz.newInstance();
    }
}