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

Inq*_*ive 37 java singleton design-patterns

我看到有人在评论说Singleton Pattern是一种反模式.我想知道为什么?

Bri*_*new 51

测试

一个原因是单身人士在单元测试中不易处理.您无法控制实例化,并且它们本质上可以在调用之间保留状态.

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

诸如Spring之类的框架将控制其对象的生命周期并经常创建单例,但这些对象由框架注入其依赖对象.因此,代码库本身并不将对象视为单例.

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

public class Portfolio {
   private Calculator calc = Calculator.getCalculator();
}
Run Code Online (Sandbox Code Playgroud)

你会注入计算器:

public class Portfolio {
   public Portfolio(Calculator c) {
      this.calc = c;
   }
}
Run Code Online (Sandbox Code Playgroud)

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

并发

通过将自己限制为对象的一个​​实例,线程的选项是有限的.可能必须保护对单件对象的访问(例如,通过同步).如果您可以维护这些对象的多个实例,那么您可以根据已运行的线程定制实例数量,并增加代码库的并发功能.

  • 那么使用单身人士的人如何处理"测试"和"并发"问题呢? (2认同)

Mik*_*tel 22

我个人认为它违反了单一责任原则.Singleton对象负责其目的和控制它们产生的实例数,我认为这是错误的.

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

  • 单身人士就像一个多神教世界中的迷你神,你的神将永远相互斗争,因为他们的关注点没有明确定义,加上如果他们包含状态,他们可以改变他们的思想,他们的行为会在调用中发生变化 (3认同)
  • 单身人士具有混合责任,因此减少了凝聚力,这对模式imo来说肯定是错误的. (2认同)

Tom*_*ine 11

[可变] Singleton是反模式的反模式.

重要的潜在反模式是全局状态(或环境状态).在全球范围内,您的整个计划中都有一个很大的依赖博客.这确实会影响测试,但这只是糟糕编程影响的一部分.

除此之外,Singleton在简单地声明可变static字段方面增加了完全不必要的复杂程度.

  • 可变静态字段存在同样的问题,它是全局状态.我没有看到使用静态字段比单例更好.关于那个的任何信息? (2认同)
  • @JuanMendes正如我所说,直截了当的可变静力学比单独的可变静力学更好,因为它们没有无意义的复杂性. (2认同)

Dam*_*mon 8

单身人士不一定是反模式,但他们只有很少的好处,并且当他们被错误使用时会变成反模式(经常发生).

通常,单身人士根本不是单身人士,而是"伪装的全球变数".此外,通常在"仅一个实例"属性实际上不具有优势时使用它们.(这也是多次同时执行错误的事实所平衡的).

除此之外,考虑多线程(通常做错了或效率低下)实现它们可能很棘手,如果你想控制它们的实例化,它们就会失去大部分好处.

如果你想控制实例化,你需要在程序的早期手工完成它,但是你也可以只创建一个普通对象的实例并将其传递给它.
如果破坏顺序有任何问题,您也需要手动实现.主功能中的单个自动对象更清晰,更容易.


Mar*_*nik 7

单身人士可能有许多要求:

  1. 懒惰的初始化;
  2. 妥善处置;
  3. 作用域(例如,每个线程一个).

通常情况下,您的应用中也会有很多单例,而Singleton模式不允许使用可重复使用的代码.所以,如果你想为所有单身人士实现所有这些顾虑,你会立即看到它的反模式质量.


Fre*_*red 5

奇怪的。单例的错误实现似乎是一种“反模式”,而不是单例本身。

我想我们已经忘记了每个程序都必须从某个地方开始。每一个抽象都必须有一个具体的实现,最终每个依赖最终都会得到解决,否则你的应用程序将没有多大用处。

大多数 DI 框架允许将类实例化为单例,它只是为您处理。如果你选择自己做 DI,注入单例不是问题。Singleton 也是可测试的,如果您使用 DI 注入它,不会使类变得不稳定。

IMO,就像其他所有模式(包括 DI 和 IoC)一样,它是一种工具。有时适合,有时不适合。