SOURCE: https://code.google.com/p/google-guice/wiki/Motivation?tm=6


normal method, dependency injection, dependency injection with GUICE


*****************************************************************************


--Direct constructor calls


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);


     return result.wasSuccessful()

         ? Receipt.forSuccessfulCharge(order.getAmount())

         : Receipt.forDeclinedCharge(result.getDeclineMessage());

    } catch (UnreachableException e) {

     transactionLog.logConnectException(e);

     return Receipt.forSystemFailure(e.getMessage());

   }

 }

}


----------------------------------------------------

--Factories

public class CreditCardProcessorFactory {


 private static CreditCardProcessor instance;


 public static void setInstance(CreditCardProcessor creditCardProcessor) {

   instance = creditCardProcessor;

 }


 public static CreditCardProcessor getInstance() {

   if (instance == null) {

     return new SquareCreditCardProcessor();

   }

   return instance;

 }

}


--client code:

public class RealBillingService implements BillingService {

 public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {

   CreditCardProcessor processor = CreditCardProcessorFactory.getInstance();

   TransactionLog transactionLog = TransactionLogFactory.getInstance();


   try {

     ChargeResult result = processor.charge(creditCard, order.getAmount());

     transactionLog.logChargeResult(result);


     return result.wasSuccessful()

         ? Receipt.forSuccessfulCharge(order.getAmount())

         : Receipt.forDeclinedCharge(result.getDeclineMessage());

    } catch (UnreachableException e) {

     transactionLog.logConnectException(e);

     return Receipt.forSystemFailure(e.getMessage());

   }

 }

}


--------------------------------------------------------------

-- unit test


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 creditCardProcessor = new FakeCreditCardProcessor();


 @Override public void setUp() {

   TransactionLogFactory.setInstance(transactionLog);

   CreditCardProcessorFactory.setInstance(creditCardProcessor);

 }


 @Override public void tearDown() {

   TransactionLogFactory.setInstance(null);

   CreditCardProcessorFactory.setInstance(null);

 }


 public void testSuccessfulCharge() {

   RealBillingService billingService = new RealBillingService();

   Receipt receipt = billingService.chargeOrder(order, creditCard);


   assertTrue(receipt.hasSuccessfulCharge());

   assertEquals(100, receipt.getAmountOfCharge());

   assertEquals(creditCard, creditCardProcessor.getCardOfOnlyCharge());

   assertEquals(100, creditCardProcessor.getAmountOfOnlyCharge());

   assertTrue(transactionLog.wasSuccessLogged());

 }

}


************************DEPENDENCY INJECTION*****************************************************

--DEPENDENCY INJECTION:



public class RealBillingService implements BillingService {

 private final CreditCardProcessor processor;

 private final TransactionLog transactionLog;


 public RealBillingService(CreditCardProcessor processor,

     TransactionLog transactionLog) {

   this.processor = processor;

   this.transactionLog = transactionLog;

 }


 public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {

   try {

     ChargeResult result = processor.charge(creditCard, order.getAmount());

     transactionLog.logChargeResult(result);


     return result.wasSuccessful()

         ? Receipt.forSuccessfulCharge(order.getAmount())

         : Receipt.forDeclinedCharge(result.getDeclineMessage());

    } catch (UnreachableException e) {

     transactionLog.logConnectException(e);

     return Receipt.forSystemFailure(e.getMessage());

   }

 }

}


--TEST

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 creditCardProcessor = new FakeCreditCardProcessor();


 public void testSuccessfulCharge() {

   RealBillingService billingService

       = new RealBillingService(creditCardProcessor, transactionLog);

   Receipt receipt = billingService.chargeOrder(order, creditCard);


   assertTrue(receipt.hasSuccessfulCharge());

   assertEquals(100, receipt.getAmountOfCharge());

   assertEquals(creditCard, creditCardProcessor.getCardOfOnlyCharge());

   assertEquals(100, creditCardProcessor.getAmountOfOnlyCharge());

   assertTrue(transactionLog.wasSuccessLogged());

 }

}



 public static void main(String[] args) {

   CreditCardProcessor processor = new PaypalCreditCardProcessor();

   TransactionLog transactionLog = new DatabaseTransactionLog();

   BillingService billingService

       = new RealBillingService(creditCardProcessor, transactionLog);

   ...

 }





*****************************DEPENDENCY INEJCTION WITH GUICE************************************************





 public class BillingModule extends AbstractModule {

 @Override

 protected void configure() {

   bind(TransactionLog.class).to(DatabaseTransactionLog.class);

   bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);

   bind(BillingService.class).to(RealBillingService.class);

 }

}


public class RealBillingService implements BillingService {

 private final CreditCardProcessor processor;

 private final TransactionLog transactionLog;


 @Inject

 public RealBillingService(CreditCardProcessor processor,

     TransactionLog transactionLog) {

   this.processor = processor;

   this.transactionLog = transactionLog;

 }


 public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {

   try {

     ChargeResult result = processor.charge(creditCard, order.getAmount());

     transactionLog.logChargeResult(result);


     return result.wasSuccessful()

         ? Receipt.forSuccessfulCharge(order.getAmount())

         : Receipt.forDeclinedCharge(result.getDeclineMessage());

    } catch (UnreachableException e) {

     transactionLog.logConnectException(e);

     return Receipt.forSystemFailure(e.getMessage());

   }

 }

}


public static void main(String[] args) {

   Injector injector = Guice.createInjector(new BillingModule());

   BillingService billingService = injector.getInstance(BillingService.class);

   ...

 }