Guice-如何实现返回不同实现的工厂 - java

可以说我有一个叫做Guice服务的服务,这是它的构造函数

public GuiceService(IPayment payment) {
    this.payment = payment;
}

我的代码曾经使用枚举创建它

IPayment payment = new PaymentFactory.create(PaymentType.Cash);
NaiveService naiveService = new NaiveService(payment);

而且我必须在某处进行工厂实施。像这样

public IPayment create(PaymentType paymentType) {
    IPayment cardPayment = null;
    switch (paymentType) {
        case Cash:
            cardPayment = new CashPayment(100);
            break;
        case Card:
            cardPayment = new CardPayment(10, 100);
            break;
    }
    return cardPayment;

现在,我想使用Guice,我想我想使用FactoryModuleBuilder。

  • 如果我对IPayment的了解不止一种,怎么办?
    (例如,CardPayment,CashPayment)
    这适用于一个
    install(new FactoryModuleBuilder()
       .implement(IPayment.class, CashPayment.class)
       .build(IPaymentFactory.class));
    
  • 如何实现构造函数?
    还能获得IPayment吗?还是会得到Guice创建的factoryImpl?
  • 谢谢

    参考方案

    您现有的实现是最好的。

    为了清楚起见,让我们写出一个通用的IPaymentFactory:

    public interface IPaymentFactory {
      IPayment create(/* ... */);
    }
    

    因此,IPaymentFactory的实例定义了一个方法,该方法接受一些参数并返回IPayment的实例。您可以自己编写一个实现,当然也可以编写一个实现,但是Guice的FactoryModuleBuilder自动提供了这样的接口实现。您无需再定义该类的任何其他内容:Guice将为您连接构造函数,并将其绑定到IPaymentFactory,以便您可以注入IPaymentFactory实例,使用参数调用create(...)并获取IPayment实例。

    看起来您要寻找的是一个需要枚举的工厂:

    public interface IPaymentFactory {
      IPayment create(PaymentType paymentType);
    }
    

    ...但是鉴于CashPayment接受一个任意参数,而CardPayment接受两个任意参数,并且鉴于它们之间的选择需要映射到任意PaymentType枚举,因此您没有给Guice提供足够的信息来构造正确的对象。

    Guice FactoryModuleBuilder设计用于结合构造函数参数和依赖项:

    // Constructor:
    @Inject public BitcoinPayment(
        @Assisted long value,         // varies by instance as a constructor parameter
        BitcoinService bitcoinService // passed-in dependency satisfied by Guice
        ) { /* ... */ }
    
    // Factory interface:
    public IBitcoinPaymentFactory {
      BitcoinPayment create(long value); // users don't need to know about dependencies!
    }
    
    // Factory binding...
    install(new FactoryModuleBuilder().build(IBitcoinPaymentFactory.class));
    
    // ...which lets Guice write the equivalent of:
    public GeneratedBitcoinPaymentFactory implements IBitcoinPaymentFactory {
      @Inject Provider<BitcoinService> bitcoinServiceProvider;
    
      @Override public BitcoinPayment create(long value) {
        return new BitcoinPayment(value, bitcoinServiceProvider.get());
      }
    }
    

    一方面,工厂比您想象的要笨:它只是将参数与依赖项结合在一起,以获得一个完整的列表。另一方面,它很方便:只需指定一次依赖项列表,剩下的就由Guice完成。

    概述: FactoryModuleBuilder不能解决您的问题,但是它可以帮助您为CashPayment和CardPayment创建工厂,然后将它们注入到手动的PaymentFactory实现中(它们仍然需要以某种形式存在)。

    附言在您的示例中,这可能是演示的“玩具问题”,您可能不需要使用Guice。对于需要依赖关系的服务对象,Guice是一个很好的解决方案,但是可以直接使用构造函数来构造数据对象(例如付款)或其他不需要依赖关系的对象(例如GuiceService或NaiveService)。一旦他们开始需要Guice注入的依赖关系,就很容易使他们了解Guice。

    java:继承 - java

    有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

    Eclipse-Google Guice - java

    我一直在尝试在eclipse插件开发中使用Google Guice。我已经将Guice jar导入为另一个插件项目。但是,Guice无法以某种方式注入依赖性。有任何想法吗???这是错误消息com.google.inject.ConfigurationException: Guice configuration errors: 1) No implementa…

    Java:线程池如何将线程映射到可运行对象 - java

    试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

    如何在带有Guice注入的play框架中模拟Authenticator? - java

    我有一个带有经过验证的路线的游戏应用程序。我实现了一个Authenticator,将用户存储到elasticsearch中。我控制器中的安全方法使用@Security.Authenticated注释进行注释。对于使用嘲笑的单元测试,我想模拟这个类,但是我不知道该怎么做。我在Guice中使用DI。所以我尝试了这种方法:开发一个AuthenticatorWrap…

    JAVA:字节码和二进制有什么区别? - java

    java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…