我正在使用 Google Guice 进行依赖项注入(inject)。假设我有以下内容:
public interface Payment {
public void pay();
}
public class PaymentCardImpl implements Payment {
public void pay() {
System.out.println("I pay with a card");
}
}
public class PaymentCashImpl implements Payment {
public void pay() {
System.out.println("I pay cash");
}
}
public class Order {
private Payment payment;
@Inject
public Order(Payment payment){
this.payment=payment;
}
public void finishOrder(){
this.payment.pay();
}
}
在此基础上,是一个非常简单的绑定(bind)模块,如下所示:
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Payment.class).to(PaymentCashImpl.class);
}
}
如您所见,Payment
实例被注入(inject)到 Order 构造函数中。这是在 MyModule
类中完成的,总体来说非常酷。
我的主图是这样的:
public static void main(String[] args) {
MyModule module = new MyModule();
Injector injector = Guice.createInjector(module);
Order order = injector.getInstance(Order.class);
order.finishOrder();
}
然而,我看不到的是,我可以如何结合某种方式来有条件地绑定(bind) PaymentCardImpl
或 PaymentCashImpl
实例到 Order
构造函数。
例如,假设该订单是“在线”订单。然后我需要这样做:
bind(Payment.class).to(PaymentCardImpl.class);
执行此操作的最佳方法是什么?我是依赖注入(inject)的新手。
最佳答案
依赖注入(inject)对于创建service
风格的对象很有用。它们具有以下特征:-
- 可能会有多个实现,
- 重行为,
- 内部状态仅限于它们的依赖关系,它们通常是不可变的
- 将映射到现实世界中的 Actor (例如收银员),而不是事物
基于此,Payment
是一个服务对象。我会将其重命名为 PaymentService
,以区别于您可能存储的有关付款的账本条目(这将是一个值对象)。
你的例子并没有说明 Order
类的作用,但我假设它会保存一些信息,比如一些订单项、送货地址和总金额。这是一个 value
对象。它代表业务领域中的一个事物。
值对象重状态,轻行为。多种实现是可能的,但您不太可能希望将一种实现替换为另一种实现。
值对象不是由您的依赖注入(inject)框架创建的。它们是由您的业务逻辑代码创建的。在您的示例中,您正在使用 Guice 创建所有对象。我希望在现实中您需要根据用户输入在运行时创建 Order
。
服务对象可以依赖于值对象,但绝不能反过来。我认为您应该寻求实现:
checkoutService.payfor(顺序, 方法);
而不是 order.finishOrder( 方法 )
在 CheckoutService
类中,您可以选择合适的 PaymentService
并将 order
传递给它。 CheckoutService
会将 PaymentCardPaymentService
(相当于您的 PaymentCardImpl)和 CashPaymentService
(相当于您的 PaymentCashImpl)作为构造函数参数。
关于java - 基于条件的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6968474/