Google Guice学习
在学习Cointrader的代码时候,要用到Google的guice用于依赖注入(Dependence Injection)。所以,在这里系统的学习一遍。这里我主要是对其官方文档进行有选择性的学习翻译。
动机
写类对象之间的组合关系是非常麻烦的一件事情。这里以一个网站订披萨作为案例:
public interface BillingService {
/**
* Attempts to charge the order to the credit card. Both successful and
* failed transactions will be recorded.
*
* @return a receipt of the transaction. If the charge was successful, the
* receipt will be successful. Otherwise, the receipt will contain a
* decline note describing why the charge failed.
*/
Receipt chargeOrder(PizzaOrder order, CreditCard creditCard);
}
直接用构造函数调用
public class RealBillingService implements BillingService {
public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
CreditCardProcessor processor = new PaypalCreditCardProcessor();//
TransactionLog transactionLog = new DatabaseTransactionLog();//这两个直接在构造函数里面构造,不利于模块化和单元测试
try {
ChargeResult result = processor.charge(creditCard, order.getAmount());
transactionLog.logChargeResult(result);
private final PizzaOrder order = new PizzaOrder(100);
private final CreditCard creditCard = new CreditCard("1234", 11, 2010);
private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog();
private final FakeCreditCardProcessor processor = new FakeCreditCardProcessor();
@Override public void setUp() {//设置
TransactionLogFactory.setInstance(transactionLog);
CreditCardProcessorFactory.setInstance(processor);
}
@Override public void tearDown() {//重置
TransactionLogFactory.setInstance(null);
CreditCardProcessorFactory.setInstance(null);
}
public void testSuccessfulCharge() {//测试
RealBillingService billingService = new RealBillingService();
Receipt receipt = billingService.chargeOrder(order, creditCard);
和工厂方法一样,依赖注入也是一种代码实现上的设计模式,它的原则是“separate behavior from dependency resolution”。
public class RealBillingService implements BillingService {
private final CreditCardProcessor processor;
private final TransactionLog transactionLog;
这时候,不需要任何工厂类:
public class RealBillingServiceTest extends TestCase {
private final PizzaOrder order = new PizzaOrder(100);
private final CreditCard creditCard = new CreditCard("1234", 11, 2010);
private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog();
private final FakeCreditCardProcessor processor = new FakeCreditCardProcessor();
public void testSuccessfulCharge() {
RealBillingService billingService
= new RealBillingService(processor, transactionLog);
Receipt receipt = billingService.chargeOrder(order, creditCard);