单例设计模式:陷阱 [已关闭]
2022-09-02 00:09:15
不确定使用严格的全局状态实现的失败。什么时候单例不适合某个应用程序?
不确定使用严格的全局状态实现的失败。什么时候单例不适合某个应用程序?
如果你正在做单元测试,Singleton通常是一个坏主意,并且不做单元测试(或BDD或验收测试)通常是一个坏主意。
使对象具有全局状态意味着您编写的涉及这些对象的单元测试将彼此隔离且脱节。相反,您将不得不担心为每个测试重置状态,并相信我...这永远不会100%完成。如果不重置全局状态,那么您将开始变得非常奇怪且难以调试测试中的错误,从而浪费时间。
全局状态还会增加代码中的耦合,并使其非常难以重构。
理想的方法是使用 IoC/DI 容器(Spring、Guice 等)来请求对象。这些容器通常具有使对象显示为“单例”的方法,但它们也有根据情况修改该行为的方法(即单元测试与域代码)。
当然,这一切都取决于您问题的大小。如果你正在一个4级测试台一起尝试一些东西,那么继续使用Singleton。但是,一旦该项目开始生活并变得越来越大,越来越复杂,那么就重构了Singleton。
Google Tech Talks前段时间有一个关于Global State和Singletons的精彩演讲。静态单例模式是邪恶的,因为它会导致不必要的副作用,并使代码无法测试。静态单例是全局变量的 OO 版本。
解决方案是只创建对象的一个实例,并通过依赖关系注入将其传递给其用户。DI 框架(如 Guice)使定义好的单例变得容易(在 Guice 中,只需用 @Singleton 注释类)。有一个类似的技术讲座叫做“不要寻找东西!”,它更多地讨论了DI。