为什么在Java代码中实现单例模式(有时)被认为是Java世界中的反模式?

2022-09-01 04:48:42

我看到SO中的一些人评论说单例模式是一种反模式。我想知道为什么?


答案 1

测试

其中一个原因是单例不容易使用单元测试进行处理。您无法控制实例化,并且从本质上讲,实例化可能会在调用之间保留状态。

因此,依赖注入原则很受欢迎。每个类都注入(配置)它们需要运行的类(而不是通过单例访问器派生),因此测试可以控制要使用的依赖类实例(并在需要时提供模拟)。

像Spring这样的框架将控制其对象的生命周期,并且经常创建单例,但这些对象由框架注入到它们的依赖对象中。因此,代码库本身不会将对象视为单例。

例如,而不是这个(例如)

public class Portfolio {
   private Calculator calc = Calculator.getCalculator();
}

你会注入计算器:

public class Portfolio {
   public Portfolio(Calculator c) {
      this.calc = c;
   }
}

因此,对象不知道/关心存在多少个实例。测试可以注入一个虚拟对象,使测试变得容易。PortfolioCalculatorCalculator

并发

通过将自己限制为对象的一个实例,线程处理的选项受到限制。对单例对象的访问可能必须受到保护(例如,通过同步)。如果可以维护这些对象的多个实例,则可以根据正在运行的线程定制实例数,并提高代码库的并发功能。


答案 2

我个人的观点是,它违反了单一责任原则。Singleton对象既负责它们的目的,又控制它们产生的实例数量,我认为这是错误的。

这就是为什么很多人将控制权委托给工厂对象的原因。


推荐