单例模式

24
什么时候应该使用单例模式,为什么?

3
那只是我的看法,但无论用什么语言,你都应该尽量避免这种情况。 - zneak
你可以在这里找到答案:http://zuta-developer.blogspot.com/2012/06/singleton-pattern.html。在那里,你将看到Singleton模式的真实世界示例和完整解释。 - ZuTa
以下是一些相关问题: - dzhu
12个回答

32

http://sites.google.com/site/steveyegge2/singleton-considered-stupid

这篇文章讨论了单例模式的问题。作者认为,单例模式之所以备受青睐,是因为它是非面向对象编程的一种回归,是对《设计模式》一书概念理解不足的救命稻草。但实际上,单例模式有很多问题,其中包括内存管理和资源限制等。由于无法判断谁持有单例实例的引用,会导致内存泄漏问题。同时,如果单例实例有对某些有限资源的引用(如数据库或文件句柄),则可能需要在程序结束前一直保持其打开状态。

d) 另一个问题是单例模式在语法上很冗长; 大多数语言都不支持它(好吧,Ruby确实支持,可惜那可能是在Matz知道更好的方法之前),所以你不仅要在单例中插入样板代码,还要在每个使用它的人中插入。

e) 然后还有子类化的问题。几乎不可能对单例进行子类化,如果你成功了,那么你一开始就不应该使用单例。你甚至不想去那里。我走过一些路,我不敢回忆起来。假装你不能做到这一点,你会节省极大的痛苦。

f) 静态方法像花岗岩一样灵活。每次使用一个静态方法,你都在将程序的一部分硬编码。只要确保你没有把脚卡在那里,当你看着它变硬时。总有一天,你会惊讶地发现,该死的PrintSpooler类确实需要另一种实现,它应该是一个接口、一个工厂和一组实现类。呃!

别以为这就是所有的问题。还有许多其他问题。例如,尝试添加多线程并查看会发生什么。我会告诉你发生了什么: 一半的时间,你会得到一个Doubleton或Tripleton,除非你是一个同步专家,拥有一个Tripleton就像在你的茶会上出现三个巨魔那样不可取并且即使你是一个同步专家,并正确使用了双重检查习惯用语,你仍然有一个巨魔要处理,而他们可不是什么好东西。

但这些问题都相比于大问题——单例"模式"鼓励你忘记你所知道的关于OO设计的一切,因为OO很难,过程化容易……


2
这真是太有趣了,这是我得到的点赞最多的答案之一 :) - Mike Mooney

7

Java Runnable 是单例模式的最佳示例。当您想要添加限制以不允许创建特定类的多个实例时,最好实现 Singleton Pattern。 实现单例模式的关键点:

  • Private Constructor
  • Static Private Instance Variable of Singleton class itself
  • Public getter method only at very first time it will initialize above variable, and always return same instance of a Singleton class.

    class Singleton {
    
          private static Singleton instance;
    
          private Singleton(){
          }
    
          public static Singleton getInstance(){
             if(instance=null){
                instance=new Singleton();
             }
    
             return instance;
          }
          ........
        }
    

    And for thread safety : getInstance() needs to be synchronized.


6
如果您的情况需要一个对象来协调系统中的操作,那么您可以使用这种模式。一个很好的例子就是Facade,因为通常需要一个Facades对象在整个系统中进行实现。
但是一般情况下,这是一个不好的做法,并且应该尽量避免,主要原因是它会极大地抑制可扩展性。

2
理论上:当你需要将一个对象的实例限制为一个时。 实际上:从来没有这种情况。

1
单例模式旨在确保一个类只有一个实例,并提供对它的全局访问点。

1

当您不想创建多个相同类型的实例时,需要使用单例模式。但是,如果您使用静态类,则可以实现相同的效果。因此,关键在于控制实例的创建,从而避免不必要的资源消耗。


1

单例模式的目的是确保只有一个类的实例被实例化。

单例模式被认为是GOF模式目录中的“糟糕”模式之一,因为单例会导致代码耦合,并使代码(单元)测试变得困难。后者在(大多数)动态/弱类型语言中并非完全正确,因为您可以对代码进行monkey patch。

让我们来看看耦合:每个使用单例的代码片段都直接与单例的实现耦合。这很难/不可能进行模拟测试,而且由于单例通常用于基础设施服务,例如数据库访问层,因此您要测试的单元与数据库访问层的具体实现相耦合。但是对于单元测试,您不想访问数据库,而是想要一些模拟数据访问层。您最终会陷入这样的情况:为什么要使用单例模式。

我建议仅将单例模式用于“简单”的软件,但众所周知,软件有增长的趋势。开始简单,几年后变得复杂。


1

考虑那些多个实例将导致错误(不一致)的情况。这可能是应用程序对象(应用程序的根对象)或应用程序范围内的 securityManager 等。单例只是一种强制要求类只能拥有一个实例的方式。


0

当你只需要一个类的实例时,最好的例子之一就是日志记录器。你只需要它的一个实例。


0
  • 在软件工程中,单例模式是一种设计模式,它限制了一个类的实例化只能有一个对象。当系统需要协调跨系统的操作时,这非常有用。

  • 应用程序需要一个且仅需要一个对象实例。此外,延迟初始化和全局访问是必要的。

更多内容请参见...

http://www.dzone.com/links/r/java_ee_singleton_design_pattern_introduction.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接