简体   繁体   English

什么时候单例类优于仅具有静态方法的类?

[英]when is a singleton class preferred over a class that has only static methods?

When is a singleton class preferred over a class that has only static methods and a private default constructor? 什么时候单例类比仅具有静态方法和私有默认构造函数的类优先?

Please vote. 请投票。

When is a singleton class preferred over a class that has only static methods and a private default constructor? 什么时候单例类比仅具有静态方法和私有默认构造函数的类优先?

When you need an instance . 当您需要一个实例时 For example, to pass as method argument. 例如,作为方法参数传递。

Use a singleton to better control when initialization occurs. 使用单例来更好地控制初始化发生的时间。 With a static class, any initialization must be at class load-time, which you have little control over. 对于静态类,任何初始化都必须在类加载时进行,而您几乎无法控制。 For example, a simple reference to a static final MEMBER will trigger class loading. 例如,对静态最终MEMBER的简单引用将触发类加载。 With a singleton, initialization can trivially be deferred till much later - typically, till first time of use. 使用单例,初始化可以被推迟到很晚以后-通常,直到第一次使用。

Reasons to delay initialization may be: 延迟初始化的原因可能是:

  • it's expensive and you don't always need it for that class 它很贵,而且您在该课程中并不总是需要它
  • you can't initialize till some other resource is initialized (say, a database connection). 您必须先初始化一些其他资源(例如,数据库连接),然后才能进行初始化。 In this case, a lazily-instantiated singleton often provides correct order of operations without any explicit control - if it's not referenced till after the other resource is initialized, everything happens for free. 在这种情况下,懒惰实例化的单例通常会提供正确的操作顺序,而没有任何显式的控制-如果在其他资源初始化之后才引用它,则所有操作都是免费的。

Use a singleton to improve testability. 使用单例来提高可测试性。 If you need to make some kind of mock object (in the broad sense) of the singleton in order to test its clients, one way to do it is to put an interface on its use, and supply a test singleton that's of a different class but implements the same interface. 如果您需要为单例创建某种模拟对象(广义上)以测试其客户端,则一种方法是使用其接口,并提供不同类的测试单例但实现相同的接口。

Using a singleton makes initialization testing easier as well. 使用单例也使初始化测试更加容易。

Use a singleton when you might need to debug initialization. 当您可能需要调试初始化时,请使用单例。 Stack traces from static initialization can be puzzling. 来自静态初始化的堆栈跟踪可能令人困惑。 Debugging can be puzzling too. 调试也可能令人费解。 If the class is loaded early, it may break before a breakpoint on the first line in main() is even hit. 如果该类过早加载,则它可能在甚至击中main()第一行中的断点之前就中断了。

If you have some state you need to store, a singleton is the way to go. 如果您有某种状态需要存储,那么单例是可行的方法。 For instance, if your class needs to load some configuration from a properties file. 例如,如果您的类需要从属性文件中加载某些配置。

The main reason for only having static methods is when you just need a toolbox to pack some functions together. 仅拥有静态方法的主要原因是,您只需要一个工具箱即可将某些功能打包在一起。

I use singletons for mainly two reasons: 我使用单例主要有两个原因:

  1. It is really expensive (time or memory) to construct the object, and I want to only ever do it once. 构造对象真的很昂贵(时间或内存),我只想做一次。
  2. The data associated with the class needs to be the same in every instance of the class. 与该类关联的数据在该类的每个实例中都必须相同。

Static method is not dynamic, this is a big different with singleton class instance. 静态方法不是动态方法,这与单例类实例大不相同。 So if you need to extends from a class and override some method, the second way won't work. 因此,如果您需要从类扩展并重写某些方法,则第二种方法将行不通。

And the for the second way, you may need to use some static references which may lead to memory leak. 第二种方法,您可能需要使用一些静态引用,这可能会导致内存泄漏。

I would say that a singleton class would be preferred only in one case: when you have some configuration to store that is system wide, will rarely (if ever) need to be refreshed. 我会说单例类仅在以下情况下才是首选:当您要存储系统范围内的某些配置时,很少(如果有的话)需要刷新。

As an example of what I mean, I have a singleton pattern in one of my applications that represents the NAT device of the user's internet connection. 作为我的意思的示例,我的一个应用程序中有一个单例模式,它表示用户互联网连接的NAT设备。 This application is intended for desktop use, and so would rarely (if ever) see a change in the internet connection. 此应用程序仅供桌面使用,因此很少(如果有的话)看到互联网连接发生变化。 Presumably the user could carry their laptop to a new location, and this would change; 大概用户可以将笔记本电脑搬到新的位置,并且情况会有所变化; however, there is a method to recreate the state in this event, but this is very infrequently changed state that can take several seconds to initialize. 但是,有一种方法可以在此事件中重新创建状态,但是这种状态很少更改,可能需要花费几秒钟来初始化。

This need to keep expensive, infrequently changing, and globally applicable state is best done by either an application scoped bean (my preferred option) or a singleton pattern bean. 这需要保持昂贵,不经常更改的状态,并且全局适用的状态最好由应用程序范围的Bean(我的首选)或单例模式Bean来完成。 Static methods aren't as good for preserving this kind of state, though you could also accomplish this using static fields as well to make a pseudo-singleton. 静态方法不能很好地保存这种状态,尽管您也可以使用静态字段来完成此操作以创建伪单例。 (Not sure if there's a better name for this - probably) (不确定是否有更好的名称-可能)

In general, my recommendation is not to use singleton like patterns if you can avoid it, as it makes re-use more difficult. 通常,我的建议是如果可以避免,则不要使用类似单例的模式,因为这样会使重用更加困难。 If you're using a CDI framework, scope your bean at the application level for easier re-use. 如果您使用的是CDI框架,请在应用程序级别对bean进行范围划分,以便于重新使用。 (This may not be a concern of yours - if not, you may safely ignore this advice) (这可能不是您的担心-否则,您可以放心地忽略此建议)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM