先说结论
看了几篇文章,
我个人对依赖注入的理解是,依赖注入更擅长解决一个 ”引用传递“ 的问题;
对单例的理解是,如果某类被许多类引用,且是一个比较稳定的变量不需要逐层传递,则使用单例更好;
单例模式
单例是一种设计模式,它表示在整个应用程序的声明周期中,某个类只有一个实例。单例模式的典型实现如下:
public class BankGateway {
public static BankGateway Instance = new BankGateway();
private BankGateway(){}
public void TransferMoney(){
System.out.println("transferring money to family");
}
}
注意:构造方法是私有的(private),所以唯一的创建实例的方式就是通过 Instance 属性,而属性是静态的(static),意味着该实例与应用程序的声明周期相绑定。
public class Processor
{
public void Process()
{
BankGateway.Instance.TransferMoney();
}
}
关于单例模式的主要抱怨是,它本质上充当了一个全局变量,从而阻碍了一定的测试性。
依赖注入
依赖注入也是一种设计模式,代表着将依赖传递给使用它们的对象,上面的代码可以用下面的方式重写:
public interface IBankGateway {
void TransferMoney();
}
public class BankGateway implements IBankGateway{
@Override
public void TransferMoney() {
System.out.println("transferring money to family");
}
}
public class Processor {
private IBankGateway iBankGateway;
public Processor(IBankGateway gateway){
iBankGateway = gateway;
}
public void process(){
iBankGateway.TransferMoney();
}
}
上面的代码是可测试的。我们可以创建一个假的银行网关,把它传递给处理器,确保它用它来转账。
单例 vs 依赖注入
大多数情况下依赖注入的模式更可取。如果有一个不稳定的依赖,把这个依赖注入到依赖类中是一个好习惯。除了更强的可测试性,这种实现方式显示地指定它需要地一切。
然而,仍有一些依赖关系更适合使用 Singleton 表示,它们是环境依赖项,环境依赖是指跨越多个类和多个层的依赖,它们作为应用程序的横切关注点。
https://enterprisecraftsmanship.com/posts/singleton-vs-dependency-injection/