2010-07-23 55 views
15

我们什么时候应该使用Singleton模式,为什么?单身模式

+3

这只是我,但你应该尽量避免。不管语言如何。 – zneak 2010-07-23 15:09:08

+0

你可以在这里找到答案(http://zuta-developer.blogspot.com/2012/06/singleton-pattern.html)。在那里你会看到真实世界的例子和Singleton模式的完整解释。 – ZuTa 2012-07-01 10:28:23

+0

这里有一些相关的问题: [1]:HTTP://计算器。问题/问题/ 137975 /什么是如此糟糕的关于单身人士 [2]:http://stackoverflow.com/questions/519520/difference-between-static-class-and-singleton-pattern – dzhu 2015-06-06 04:00:19

回答

1

理论上:当您需要将对象的实例化限制为一个实例时。在实践中:从不。

3

如果您遇到需要确切一个对象来协调整个系统的操作的情况,那么您可以使用此模式。 Facade就是一个很好的例子,也就是说Facade可以作为单例实现,因为在整个系统中通常需要一个Facade对象。

但是总的来说,这通常是一种不好的做法,应该避免,一个很大的原因是它极大地抑制了可扩展性。

17

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

为什么辛格尔顿如此大的吸引力?我会第一个承认:我也喜欢。不,从头开始 - 我爱上了辛格尔顿。从我看到它的那一刻起,它就像一位老朋友。它简单而美丽。

我会告诉你为什么:这是因为Singleton模式是非OO编程的倒退。对于那些不了解“四人帮”试图说出的单词的人来说,这是一条生命线。我不知道它是如何进入的 - 首先是一些政治OOPSLA的压力 - 但它不属于那里。它的邪恶......

这里的“短”总之......

一)我还没有涉及的问题,甚至是十分之一。但我会列举其中的一些。

b)一个是内存管理;一个Singleton基本上只是一个内存泄漏,如果没有人会使用它一段时间。但是你不知道什么时候可以释放它,因为没有人会打电话给你,并说“没有人会用你一段时间!”

此外,你不能分辨谁在你的Singleton实例的引用周围,因为你是非常唠叨交出,是不是? (注意:Java的弱引用可以帮助解决这个问题)。

c)说到内存泄漏,如果您的Singleton对某些有限资源(如数据库或文件句柄)有句柄,该怎么办?我想你应该保持这个傻瓜直到你的程序结束。感谢上帝C++程序在崩溃之前永远不会超过大约10分钟,通常是因为资源耗尽,或者试图访问某人释放的单例。

d)另一个问题是Singleton设计在语法上是有噪声的;大多数语言都不支持它(很抱歉,Ruby确实如此,但是这可能在Matz知道任何更好的情况之前),所以您不仅要在Singleton中使用样板代码,而且还要使用它。

e)然后是子类化的东西。子类化一个Singleton几乎是不可能的,如果你管理它,那么你首先不应该使用Singleton。你不要甚至想去那里。我走过那些我不敢重述的道路。假装你做不到,你会为自己节省大量的痛苦。

f)静态方法与花岗岩一样灵活。每次你使用一个,你都在混凝土中投射你的程序的一部分。当你看着它变硬的时候,确保你的脚没有堵塞。有一天,你会惊讶于你真的需要另一个实现PrintSpooler类的实现,它应该是一个接口,一个工厂和一组实现类。 D'哦!

不要以为这一切。还有很多其他问题。例如,尝试添加多线程并查看会发生什么。好吧,我会告诉你发生了什么事情:一半时间,你会得到一个Doubleton或一个Tripleton,除非你是同步专家,而拥有一个Tripleton与在你的茶会上出现三个炎魔一样可取。即使你是一位同步专家,并获得了双重检查的成语,你仍然有一个Balrog来处理,他们不会野餐。

但是,这些问题都褪色成无足轻重相比,最大的一个,这就是单身“模式”鼓励你忘记你了解面向对象的设计,因为OO硬一切,程序很容易...

+0

伟大的链接,谢谢! – KooiInc 2010-07-23 17:07:22

+0

这真是太好笑了,这是我的最高投票答案:) – 2011-12-06 16:25:56

0

当你想要一堆不同的对象能够引用一个单一的对象。也许他们都想使用相同的PhysicsEngineDude或其他东西......当他们生活在同一个世界时,你不希望不同的物体拥有不同的物理模型!

+0

你忘了添加“...而且你太懒惰不能传递一个对需要它的对象的引用。 – 2010-07-25 13:00:19

0

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

0

当系统中只需要一个类的实例时,由于它只有一个实例,因此您可以严格决定用户如何访问它。

0

如上所述,单例模式的意图是确保实例化类的单个实例。

单身模式被认为是GOF pattern catalog中的“坏”模式之一,因为单例导致代码中的耦合并且难以对代码进行(单元)测试。后一点在(大多数)动态/松散类型语言中不是100%正确,因为您可以使用修补程序代码。让我们来看看耦合:每个使用Singleton的代码块都直接耦合到Singleton的实现。这是很难/不可能的,因为Singletons通常用于像数据库访问层这样的基础设施服务,所以您要测试的单元与数据库访问层的具体实现耦合在一起。但是对于一个单元测试你不想命中数据库,你想拥有一些模拟数据访问层。你最终会问自己为什么使用单例模式。

我建议单身模式只适用于“简单”软件,但大家都知道软件有增长的趋势。几年后开始简单并结束复杂。

1

如果你不想创建多个相同类型的实例,你需要去单身人士。但是,如果您使用静态类,则可以实现相同的功能。所以这里的要点是它不是唯一的实例,而是控制实例创建,从而避免了不必要的宝贵资源消耗。

1

想象一下多于一个实例会出现错误(不一致)的情况。这可能是一个应用程序对象(一个应用程序的根对象)或一个应用程序范围的安全管理器等。单例只是一种强制执行的方式,只能有一个实例。

0

时要强制唯一一个在你的应用程序中创建一个类的实例的Singleton模式应该被使用。这可能是因为:

  • 创建这样的对象是资源密集型

  • 对象是应用程序级的对象;因此有多个实例是没有意义的。

因此,设计这样一个单独的类是有意义的。欲了解更多信息,请参阅singleton design pattern explained with c# .net example

1

的Singleton模式是要确保一个类只有一个实例,并给它提供一个全局访问点。

4

Java Runnable单例模式的最佳示例。当你想添加的限制不允许你创造出比一类特殊的单个实例更多的则是更好地实现Singleton模式。 关键点实现单:

  • 私有构造Singleton类本身的
  • 静态私有实例可变
  • 公共getter方法只在第一次它将初始化上述变量,并且总是返回一个Singleton类的同一个实例。

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

    而对于线程安全: 的getInstance()需要同步。