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,使测试变得容易.
并发
通过将自己限制为对象的一个实例,线程的选项是有限的.可能必须保护对单件对象的访问(例如,通过同步).如果您可以维护这些对象的多个实例,那么您可以根据已运行的线程定制实例数量,并增加代码库的并发功能.
Mik*_*tel 22
我个人认为它违反了单一责任原则.Singleton对象负责其目的和控制它们产生的实例数,我认为这是错误的.
这就是为什么很多人将控件委托给工厂对象的原因.
Tom*_*ine 11
[可变] Singleton是反模式的反模式.
重要的潜在反模式是全局状态(或环境状态).在全球范围内,您的整个计划中都有一个很大的依赖博客.这确实会影响测试,但这只是糟糕编程影响的一部分.
除此之外,Singleton在简单地声明可变static字段方面增加了完全不必要的复杂程度.
单身人士不一定是反模式,但他们只有很少的好处,并且当他们被错误使用时会变成反模式(经常发生).
通常,单身人士根本不是单身人士,而是"伪装的全球变数".此外,通常在"仅一个实例"属性实际上不具有优势时使用它们.(这也是多次同时执行错误的事实所平衡的).
除此之外,考虑多线程(通常做错了或效率低下)实现它们可能很棘手,如果你想控制它们的实例化,它们就会失去大部分好处.
如果你想控制实例化,你需要在程序的早期手工完成它,但是你也可以只创建一个普通对象的实例并将其传递给它.
如果破坏顺序有任何问题,您也需要手动实现.主功能中的单个自动对象更清晰,更容易.
单身人士可能有许多要求:
通常情况下,您的应用中也会有很多单例,而Singleton模式不允许使用可重复使用的代码.所以,如果你想为所有单身人士实现所有这些顾虑,你会立即看到它的反模式质量.
奇怪的。单例的错误实现似乎是一种“反模式”,而不是单例本身。
我想我们已经忘记了每个程序都必须从某个地方开始。每一个抽象都必须有一个具体的实现,最终每个依赖最终都会得到解决,否则你的应用程序将没有多大用处。
大多数 DI 框架允许将类实例化为单例,它只是为您处理。如果你选择自己做 DI,注入单例不是问题。Singleton 也是可测试的,如果您使用 DI 注入它,不会使类变得不稳定。
IMO,就像其他所有模式(包括 DI 和 IoC)一样,它是一种工具。有时适合,有时不适合。
| 归档时间: |
|
| 查看次数: |
16865 次 |
| 最近记录: |