单例模式通常被认为是一种反模式。
线程安全问题
当多线程运行你的程序时,如果同时多个线程检测到唯一实例不存在,就会有多个实例被创建,这违反了单例模式的原则,当然通过互斥锁可以解决这个问题。
隐藏依赖
如果函数中存在类似全局的东西,而非靠参数显示传递,就是隐藏依赖,开发者总是喜欢看得见的依赖。单例是表示的是一种全局状态,也就是说单例是全局性、有状态性的。有状态的程序难于理解和调试。这就导致任何一个地方修改单例状态的副作用都会应用于其他所有使用到单例的地方,无形中两个用到单例的地方引入了隐性耦合,有悖于面向对象编程中最小化代码有状态性、解耦的原则。
给单元测试带来困难
单例的性质决定了使用它的组件难以被单元测试。因为单元测试的时候,我们会将不相关的组件“mock”掉。而单例的性质让我们很难对这个单例进行“mock”的操作(用另一个实例替换)
使用依赖注入可以避免单例模式
参考: