依赖注入
对象之间的依赖增加复杂性,导致对象之间紧耦合。
比如下面的TransferService组件依赖其他两个组件:TransferRepository和AccountRepository:
如果直接使用实例:
public class TransferService {
private AccountRepository accountRepository;
public TransferService () {
this.accountRepository = new AccountRepository();
}
public void transferMoney(Account a, Account b) {
accountRepository.transfer(a, b);
}
}
TransferService对象需要一个AccountRepository对象,实现账户A到账户B的转账功能。于是,直接增加AccountRepository的实例。这样很难维护,也很难做TransferService的单元测试。
也可以使用工厂模式实现该功能:
public class TransferService {
private AccountRepository accountRepository;
public TransferService() {
this.accountRepository = AccountRepositoryFactory.getInstance("jdbc");
}
public void transferMoney(Account a, Account b) {
accountRepository.transfer(a, b);
}
}
上面的代码,我们使用工厂模式增加AccountRepository类的对象。更好的做法是program-to-interface,针对这个具体问题,我们可以增加一个接口,降低耦合:
public interface AccountRepository {
void transfer();
//other methods
}
我们可以增加JdbcAccountRepositry类,实现AccountRepository接口:
public class JdbcAccountRepositry implements AccountRepositry{
//实现AccountRepositry定义的方法
// 实现其他方法
}
这样,由工厂类增加的对象很容易维护。使用工厂类,也可以增加可配置的对象。但是,为了降低耦合,获取协作组件的时候在业务组件里增加了工厂类。让我们看看依赖注入怎么解决这个问题。
对于依赖注入模式,我们只是定义依赖性,而不用解决对象之间的依赖。看下图,我们会在需要对象的时候注入他们:
TransferService依赖AccountRepository和TransferRepository。TransferService可以使用多种TransferRepository完成转账功能,比如可以使用JdbcTransferRepository或者是JpaTransferRepository,依赖哪个,由部署环境决定。
public class TransferServiceImpl implements TransferService {
private TransferRepository transferRepository;
private AccountRepository accountRepository;
public TransferServiceImpl(TransferRepository transferRepository, AccountRepository accountRepository) {
this.transferRepository = transferRepository;//TransferRepository is injected
this.accountRepository = accountRepository;//AccountRepository is injected
}
public void transferMoney