回答
一个单例用于将某种全局状态引入到应用程序中。如果是无状态的,我还没有看到使用单点,除非
- 您希望将其与状态,你需要一个对象实例对于一些特定的可预见的未来或
- 延长技术原因(例如,对于C#
lock
声明,虽然这已经很牵强了)或 - 您需要继承,即您希望能够轻松地用另一个使用相同接口替换您的单身人士但是不同的实现。例如,Java中的
Toolkit.getDefaultToolkit()
方法将返回一个确切类型与系统相关的单例。
我要去+1,尽管恕我直言的单身人士是滥用**引入全球国家。单例的目的不是使对象全局可用,而是强制对象仅实例化一次。全局对象是一个必要的邪恶。除非真正需要,否则应该尽量不要使用它们,因为它们通常会导致高耦合性,而SomeSingleton.getInstance()。someMethod()遍布整个地方。:) – back2dos 2010-05-04 12:19:32
对于只需一个渲染实例而不是多个渲染实例的游戏,或者在网络管道类中设置安全通道,一次只能有一个连接的情况下,它非常有用。 – Tschallacka 2015-05-19 11:14:43
“轻松取代你的单身人士”部分是我认为最重要的一点。 Rest非常接近静态类的实现。 – 2016-03-14 14:47:16
我可以看到使用无状态单例代替静态方法类的情况,即Dependency Injection。
如果您有一个直接使用的辅助函数类的实用函数,它会创建一个隐藏的依赖关系;你无法控制谁可以使用它或在哪里。通过无状态单例实例注入相同的帮助类,可以控制它在何处以及如何使用,并在需要时替换/模拟它等。
使它成为一个单例实例可以简单地确保您不再需要分配更多类型的对象(因为您只需要一个)。
*“你无法控制谁可以使用它,或者在哪里。”*为什么有人需要它? – hagrawal 2015-07-16 20:19:02
@hagrawal为了测试目的,你应该可以模拟它 – 2016-12-08 10:26:58
在大多数编程语言中,类没有涉及很多类型系统。虽然一个类,其静态方法和变量是一个对象,但它往往不能实现一个接口或扩展其他类。因为这个原因,它不能以多态的方式使用,因为它不能是另一种类型的子类型。例如,如果您有一个接口IFooable
,这是其他类别的多个方法签名所要求的,则类对象StaticFoo
不能用于代替IFooable
,而FooSingleton.getInstance()
可以(假设FooSingleton
执行IFooable
)。
请注意,正如我评论Heinzi的回答,单身人士是控制实例化的模式。它将new Class()
替换为Class.getInstance()
,这使Class
的作者可以更好地控制实例,可以使用它来防止创建不必要的实例。单身人士只是工厂模式的一个非常特殊的例子,应该这样对待。常见使用使得它成为全球注册局的特例,而这往往会导致糟糕的结果,因为全球注册局不应该被无情地使用。
如果您打算提供全局帮助函数,那么静态方法将工作得很好。该类不会充当类,而只是作为一个名称空间。我建议,你保持高凝聚力,否则你可能会遇到最古怪的耦合问题。
格尔茨
back2dos
辛格尔顿不是无状态的,它拥有全局状态。
,我可以想到用辛格尔顿的部分原因是:
- 以避免内存泄漏
- 提供所有模块相同的状态在一个应用程序如数据库连接
我知道,但实际上单身可以或多或少是无状态的......如果它不共享任何类属性... – 2010-05-04 14:39:52
其实我我们发现了另一个没有提到的答案:静态方法很难测试。
似乎大多数测试框架对于嘲笑实例方法非常有用,但其中许多框架并没有以一种体面的方式处理静态方法的模拟。
但Powermock似乎能够这样做 – 2012-03-23 10:11:58
使用哪一个之间有一个折衷。单身人士可能有也可能没有状态,他们指的是对象。如果他们不保持状态并且仅用于全局访问,那么静态更好,因为这些方法会更快。但是如果你想利用对象和OOP概念(继承多态),那么单例更好。
考虑一个例子:java.lang.Runtime是java中的单例类。这个类允许每个JVM有不同的实现。该实现对于每个JVM都是单个实现。如果这个类是静态的,我们不能通过基于JVM的不同实现。
我发现这个链接真的有用:http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?
希望它有帮助!
这个答案很适合在现实世界中包含一个具体的例子。 – systemovich 2016-11-14 14:00:56
对我来说“想对象状态使用辛格尔顿,要获取函数使用静态方法”
这取决于你想要什么。无论何时您想要对象状态(例如多态性为空状态而不是null
或默认状态),单例对您来说都是合适的选择,而静态方法在您需要函数时使用(接收输入然后返回输出)。
我推荐单例情况下,它应该始终是实例化后的相同状态。它不应该是可克隆的,也不能接收任何设置值(除了来自文件的静态配置,例如属性文件在java中)。
P.S.这两者之间的性能在毫秒级上有所不同,所以首先关注架构。
- 1. 为什么静态方法在单例实例中不可用?
- 2. 为什么getAppProperty()不是静态方法?
- 3. 为什么静态方法不能引用实例方法?
- 4. 为什么说方法不是静态时它是静态的?
- 5. 为什么实例方法不能覆盖静态方法
- 6. 为什么不是每种方法都是静态方法?
- 7. 什么时候使用类方法而不是实例方法?
- 8. 为什么文本在动画中使用而不是静态
- 9. 为什么使用静态“常量”而不是实际值?
- 10. 为什么使用singleton而不是静态类?
- 11. 静态var,方法还是单例?
- 12. 为什么我们需要一个明确的转换,而不是扩展方法而不是静态方法?
- 13. 如何使静态工厂方法不是静态实例?
- 14. 为什么在单例类中实例成员是静态的?
- 15. 为什么私有静态方法是使用任务
- 16. 为什么核心动画方法是类方法而不是实例方法?
- 17. 为什么AbstractFactoryUnit具有动态而不是静态多态?
- 18. 为什么super()不能使用__new__以外的静态方法?
- 19. 为什么在静态方法中不允许使用“this”?
- 20. 为什么不使用静态方法进行CBV?
- 21. 为什么我不应该使用静态导入Mockito方法?
- 22. 使用静态或单例类而不是System.Web.HttpRuntime.Cache?
- 23. 使用单而不是全局静态实例
- 24. 为什么可以调用非静态类的静态方法?
- 25. 为什么不使com.fasterxml.jackson.databind.ObjectMapper中的某些方法变为静态?
- 26. 什么时候应该将HTML助手作为扩展方法而不是简单的静态方法编写?
- 27. 什么是静态方法同步吗?
- 28. 什么是C#中的“静态方法”?
- 29. 什么是静态方法和变量?
- 30. 为什么接口方法不能是“静态”和“最终”?
http://stackoverflow.com/questions/720744/static-class-and-singleton – 2010-05-04 12:54:09
可能的重复不要以为我们谈论2种不同的语言,所以答案可能会有所不同,但感谢您的链接,在java从来没有听说过“monostate”这个词 – 2011-12-09 09:52:23