Java Guice-如何实现返回不同实现的工厂
假设我有一个名为Guice服务的服务,这里是它的构造函数Java Guice-如何实现返回不同实现的工厂,java,guice,factory,Java,Guice,Factory,假设我有一个名为Guice服务的服务,这里是它的构造函数 public GuiceService(IPayment payment) { this.payment = payment; } 我的代码使用枚举创建它 IPayment payment = new PaymentFactory.create(PaymentType.Cash); NaiveService naiveService = new NaiveService(payment); 我必须在某处进行工厂实施。像这样的
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
(如卡付款、现金付款)
这对一个人有效
install(new FactoryModuleBuilder()
.implement(IPayment.class, CashPayment.class)
.build(IPaymentFactory.class));
它还会被支付吗?还是会得到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());
}
}
//构造函数:
@注入公共比特币支付(
@辅助长值,//作为构造函数参数随实例而变化
BitcoinService BitcoinService//传入的依赖项由Guice满足
) { /* ... */ }
//工厂界面:
公共IBitcoinPaymentFactory{
BitcoinPayment create(长值);//用户不需要知道依赖关系!
}
//工厂装订。。。
安装(新的FactoryModuleBuilder().build(IBitcoinPaymentFactory.class));
//…这使Guice可以编写等效的:
公共生成的BitCoinPaymentFactory实现了IBitInputFactory{
@注入提供者比特币服务提供者;
@覆盖公共比特币支付创建(长值){
返回新的BitcoinPayment(值,bitcoinServiceProvider.get());
}
}
一方面,工厂比你想象的要简单:它只是将参数和依赖项结合起来,得到一个完整的列表。另一方面,它很方便:只需指定一次依赖项列表,Guice就可以完成其余的工作
总而言之:FactoryModuleBuilder不会解决您的问题,但它可以帮助您创建现金支付和卡支付工厂,然后您可以将其注入手动支付工厂实现(仍需要以某种形式存在)
另外,在您的示例中,这可能是一个用于演示的“玩具问题”,您可能不需要使用Guice。对于需要依赖关系的服务对象,Guice是一个很好的解决方案,但是数据对象(如付款)或其他似乎不需要依赖关系的对象(如GuiceService或NaiveService)可以直接使用构造函数构造。一旦他们开始需要注入Guice的依赖项,就应该很容易让他们意识到Guice