Guice - как реализовать фабрику, которая возвращает различные реализации
допустим, у меня есть сервис под названием Guice service и вот его конструктор
public GuiceService(IPayment payment) {
this.payment = payment;
}
и мой код использовался для его создания с помощью перечисления
IPayment payment = new PaymentFactory.create(PaymentType.Cash);
NaiveService naiveService = new NaiveService(payment);
и у меня должна была быть где-то заводская реализация. Что-то вроде этого!--5-->
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? или он получит factoryImpl, созданный Guice?
спасибо
1 ответов
ваша существующая реализация-это лучшее, что вы можете получить.
Давайте писать общие IPaymentFactory для ясности:
public interface IPaymentFactory {
IPayment create(/* ... */);
}
таким образом, экземпляры IPaymentFactory определяют один метод, который принимает некоторое количество параметров и возвращает экземпляр IPayment. Вы могли бы написать реализацию самостоятельно, и, очевидно, у вас есть, но FactoryModuleBuilder Guice предоставляет такие реализации интерфейса, как этот автоматически. Тебе никогда не нужно определять что-нибудь еще об этом классе: 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 (которая все равно должна существовать в той или иной форме).