什么时候单例类比仅具有静态方法的类更受青睐?
什么时候单例类比仅具有静态方法和私有默认构造函数的类更受青睐?
请投票。
When is a singleton class preferred over a class that has only static methods and a private default constructor?
Please vote.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
使用单例可以更好地控制初始化发生的时间。对于静态类,任何初始化都必须在类加载时进行,而您对此几乎无法控制。例如,对静态最终成员的简单引用将触发类加载。对于单例,初始化可以简单地推迟到很晚之后——通常是直到第一次使用。
延迟初始化的原因可能是:
使用单例来提高可测试性。如果您需要制作单例的某种模拟对象(广义上的)以测试其客户端,一种方法是放置一个接口其使用,并提供一个属于不同类但实现相同接口的测试单例。
使用单例也使初始化测试变得更容易。
当您可能需要调试初始化时,请使用单例。静态初始化的堆栈跟踪可能会令人费解。调试也可能令人困惑。如果类提前加载,它可能会在 main() 第一行的断点被击中之前中断。
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. With a singleton, initialization can trivially be deferred till much later - typically, till first time of use.
Reasons to delay initialization may be:
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.
当您需要一个实例时。例如,作为方法参数传递。
When you need an instance. For example, to pass as method argument.
仅具有静态方法的主要原因是当您只需要一个工具箱将一些函数打包在一起时。
我使用单例主要有两个原因:
我只想做一次。
类的每个实例中都需要相同。
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:
I want to only ever do it once.
needs to be the same in every instance of the class.
如果您需要存储某些状态,那么单例是最佳选择。例如,如果您的类需要从属性文件加载一些配置。
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.
静态方法不是动态的,这与单例类实例有很大不同。因此,如果您需要从类扩展并重写某些方法,则第二种方法将不起作用。
对于第二种方式,您可能需要使用一些静态引用,这可能会导致内存泄漏。
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.
我想说单例类仅在一种情况下才是首选:当您有一些要存储系统范围的配置时,很少(如果有的话)需要刷新。
作为我的意思的一个例子,我的一个应用程序中有一个单例模式,它代表用户互联网连接的 NAT 设备。该应用程序适用于桌面使用,因此很少(如果有的话)看到互联网连接发生变化。据推测,用户可以将笔记本电脑带到新的位置,这种情况将会改变;但是,有一种方法可以重新创建此事件中的状态,但这是很少更改的状态,可能需要几秒钟的时间才能初始化。
保持昂贵、不经常更改且全局适用的状态的需要最好通过应用程序范围的 bean(我的首选选项)或单例模式 bean 来完成。静态方法不太适合保留这种状态,尽管您也可以使用静态字段来完成此操作以创建伪单例。 (不确定是否有更好的名称 - 可能)
一般来说,如果可以避免的话,我的建议是不要使用类似单例的模式,因为它会使重用变得更加困难。如果您使用的是 CDI 框架,请将您的 bean 范围限定在应用程序级别,以便于重用。 (这可能不是您关心的问题 - 如果不是,您可以安全地忽略此建议)
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. 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. 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. (This may not be a concern of yours - if not, you may safely ignore this advice)