Guice学习(一)------ 工厂模式和依赖注入的好处

1.工厂模式介绍

https://blog.csdn.net/qq564425/article/details/81082242?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

2.使用工厂模式的好处

https://www.cnblogs.com/vigorz/p/10501955.html

3.使用依赖注入的好处

https://github.com/google/guice/wiki/GettingStarted

官方介绍使用依赖注入的好处主要在于,如果使用工厂模式,全局使用静态变量在内存保存一个对象:

public class CreditCardProcessorFactory {

// 工厂模式 整个项目过程中使用 instance保存该类在内存中的唯一对象,
//使用前需要初始化,即通过 setInstance方法创建
//使用完需要用setInstance(null)销毁
  private static CreditCardProcessor instance;

  public static void setInstance(CreditCardProcessor processor) {
    instance = processor;
  }

  public static CreditCardProcessor getInstance() {
    if (instance == null) {
      return new SquareCreditCardProcessor();
    }

    return instance;
  }
}
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();

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

    assertTrue(receipt.hasSuccessfulCharge());
    assertEquals(100, receipt.getAmountOfCharge());
    assertEquals(creditCard, processor.getCardOfOnlyCharge());
    assertEquals(100, processor.getAmountOfOnlyCharge());
    assertTrue(transactionLog.wasSuccessLogged());
  }
}

这段代码逻辑是:

1.初始时使用创建对象:

private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog();
private final FakeCreditCardProcessor processor = new FakeCreditCardProcessor();

2. 传给工厂类的静态变量,使得该类全局保存一个唯一的对象,使用该类都用该对象

  @Override public void setUp() {
    TransactionLogFactory.setInstance(transactionLog);
    CreditCardProcessorFactory.setInstance(processor);
  }

3.使用该对象时直接从工厂类里获取,因为前面经过初始化,所以get可以直接得到原来初始化时new的对象,而不会重复创建,造成内存浪费,内存里没有该对象时,就会返回Null.

 public static CreditCardProcessor getInstance() {
    if (instance == null) {
      return new SquareCreditCardProcessor();
    }

    return instance;
  }

4.使用完后销毁工厂类那个静态变量维护的对象

 @Override public void tearDown() {
    TransactionLogFactory.setInstance(null);
    CreditCardProcessorFactory.setInstance(null);
  }

存在问题:

这段代码很笨拙。一个全局变量保存模拟实现,所以我们需要小心设置和拆除它。如果tearDown 失败,全局变量将继续指向我们的测试实例。这可能会导致其他测试出现问题。它还阻止我们并行运行多个测试。

但最大的问题是依赖关系隐藏在代码中。如果我们添加一个依赖CreditCardFraudTracker,我们必须重新运行测试以找出哪些会中断。如果我们忘记为生产服务初始化工厂,我们在尝试收费之前不会发现。随着应用程序的增长,保姆工厂对生产力的消耗越来越大。

总结就是:

1.忘记初始化,导致每次都new新对象

2.用完忘记销毁,对其它方法造成影响

这时候使用依赖注入,把对象的创建销毁全交给Guice去做,自己无序关心对象的创建问题,注意,这里所讨论的问题是,全局维护一个共享变量时会出现的问题,如果每次都重新new,自然有GC来回收,无序担心内存溢出问题。

猜你喜欢

转载自blog.csdn.net/qq_39552268/article/details/120095880