Sin*_*hot 11
我认为Singleton模式是最不适用的设计模式.在大约12年的软件开发中,我会说我可能会看到5个合适的例子.
我参与了一个项目,我们有一个系统监控服务,用一个System类(不要与Java的内置System类混淆)为我们的系统建模,其中包含一个Subsystems 列表,每个列表都有一个Components 列表,依此类推.设计师制作System了一个单身人士.我问"为什么这是一个单身人士?" 答:"嗯,只有一个系统." "我知道,但是,你为什么要把它变成一个Singleton?难道你不能只实例化一个普通类的一个实例并将它传递给需要它的类吗?" "只是getInstance()到处打电话而不是传遍它更容易." "哦..."
这个例子很典型:单身人士经常被滥用作为访问类的单个实例的便捷方式,而不是出于技术原因强制执行唯一实例.但这需要付出代价.当一个类依赖时getInstance(),它将永远与Singleton实现绑定.这使得它不易测试,可重用和可配置.它违反了我遵循的基本规则,并且在某些设计原则文章中可能有一个共同的名称:类不应该知道如何实例化它们的依赖项.为什么?因为它将类硬编码在一起.当类调用构造函数时,它将绑定到实现.getInstance()没有什么不同.更好的选择是将接口传递给类,而其他东西可以做构造函数/getInstance()/工厂电话.这就是像Spring这样的依赖注入框架的用武之地,尽管它们不是必需的(只是非常好).
那么什么时候使用Singleton是合适的呢?在那种罕见的情况下,实例化多个东西会破坏应用程序.我不是在谈论在太阳系应用程序中实例化两个地球 - 这只是一个错误.我的意思是,如果你不止一次调用/分配/实例化它,会有一些底层的硬件或软件资源会炸毁你的应用程序.即使在这种情况下,使用Singleton的类也不应该知道它是Singleton.应该有一个且只有一个调用getInstance()返回一个接口,然后传递给需要它的类的构造函数/ setter.我想另一种说法是你应该使用Singleton来实现其"单一性"而不是"全局可访问性".
顺便说一句,在那个项目中,我提到System了Singleton ...... System.getInstance()在整个代码库中,还有其他几个不合适的单身人士.一年后,一些新要求降下来:"我们正在将系统部署到多个站点,并希望系统监控服务能够监控每个实例." 每个实例......嗯... getInstance()不会削减它:-)
有效的Java说:
Singletons typically represent some system component that is intrinsically
unique, such as a video display or file system.
Run Code Online (Sandbox Code Playgroud)
因此,如果您的组件保证整个应用程序中的单个实例并且它具有某种状态,则将其设置为单例是有意义的
在您的情况下,应用程序的设置是单身人士的一个很好的候选人.
另一方面,如果要将某些函数组合在一起,则类只能有静态方法,例如实用程序类,jdk中的示例是java.util.Arrays java.util.Collections.这些有几个相关的方法,作用于数组或集合