Singleton 是邪恶的

Singleton 是邪恶的,为什么说邪恶,因为它有陷井,或者很虚伪,容易诱骗初学者上当,我在Jdon论坛一直表达我自己这个朴素的观点,但是这种告诫却不被一些人重视,这种现象在历史上不断被重演,哥白尼不是说地球是圆的被处死了吗?当然,这个比喻可能过分了点,不要因为有人对“Singleton是邪恶的”观点有异议,就觉得它是一个遥远的神话。

"Singleton 是邪恶的",具体文章见:
http://www.pyrasun.com/mike/mt/archives/2004/11/06/15.46.14/index.html

在段落:Using the example with IoC中,第一个就是:Singletons are evil。

注意这篇文章是在最近发表的,可不是在我之前,否则又有人说我“抄袭”了。

关于为什么Singleton是邪恶的,如下:

http://c2.com/cgi/wiki?SingletonsAreEvil

http://weblogs.asp.net/scottdensmore/archive/2004/05/25/140827.aspx

反方观点:
http://www.mattberther.com/2004/05/000481.html

javaWorld导航虚伪迷惑的Singletion单态(单例)模式:
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.htmlresources

Picocontainer作者宣称Singleton是反模式,根本不是模式见:
http://www.picocontainer.org/Singleton+antipattern

本站关于使用Singleton在多线程场合下可能出现死锁的讨论见
http://www.jdon.com/jive/thread.jsp?forum=121&thread=17133


以上资料整理在这个帖子中,供大家学习参考用。

不妨听我讲一个最近的story。OOPSLA2004,Martin Fowler带着一帮人玩了个投票游戏:GoF的23个模式当中,哪些应该被淘汰出局。结果是,Factory Method、Flyweight、Bridge、Interpreter被全票淘汰,Singleton和Chain of Responsibility褒贬参半暂时苟延残喘。

如果在J2EE的范围内做一次正式的投票,我敢打赌Factory Method、Prototype、Singleton和Bridge绝对是在被淘汰之列,因为它们做的事情已经完全被支持Dependency Injection的容器包办了,程序员再也不需要知道这些模式。所以说呢,“Singleton是邪恶”的或者是一个非伪命题,不过更可能是一个伪问题,因为……谁还需要Singleton呢?你只需要PicoContainer或者Spring Core。

这篇文章很好,对IOC的分析很透彻,谢谢banq。

应该说singleton在多线程下会存在问题比较准确。spring在创建对象的时候还是有两种模式,这似乎是无法回避的。

> 应该说singleton在多线程下会存在问题比较准确。spring在?
> 建对象的时候还是有两种模式,这似乎是无法回避的。

这跟Spring有什么关系呢?如果说有的话,恰好是Spring的“singleton=true”的配置让我们再也不必自己实现Singleton,再也不必面对Singleton的种种evil。毕竟你终归是要使用全局唯一实例的对象的。

> Singleton
> 是邪恶的,为什么说邪恶,因为它有陷井,或者很虚伪,容易诱骗初学者上当

不能说是上当,那是自己使用的问题,我使用了这么久、这么多次的Singleton,有台多处使用Singleton服务器(不是b/s,是c/s的)已经自己运行了很久了,从来没有碰到什么陷阱之类的问题,Singleton有很多使用方式,看你怎么用,不要把某些责任推给一个设计模式。

说到陷阱,程序处处都是陷阱,如果你使用的不当的话

其实这篇文章作者不赞同Ioc模式称为dependency injection,依赖性注射的,并且说:If you're desperate to get a job at ThoughtWorks,看来gigix也是ThoughtWorks一个忠实的追随者。

对于Martin Fowler的贫血模型我是不敢苟同的,我们一直使用实体Bean作为Domain Model的实现方式之一;Session Bean作为Transaction Script实现,设计模式、可复用的以POJO嵌入Transaction Script使用,这样实践起来至少我觉得不错。这篇文章的观点和实践与我非常符合:http://personal.inet.fi/koti/jukka.tamminen/objects/extreme%20OO.htm
当然,本贴不是讨论这个问题的,以后再辟新贴讨论,Martin提出贫血模型会让很多人疑惑和彷徨。

我同意Spring提供的Singleton模式之选,实际是提供全局唯一变量,但是这种情况下,也要注意在多线程情况下的死锁(条件:在Web层中使用+写操作+synchronized)。

to Azure_2003
“多处使用Singleton服务器”是否经过严格的多用户并发性能测试,死锁等性能问题只有在大量并发用户操作才会出现。建议使用loadRunner测试一下,:) 呵呵

再说初学者使用的不好的东西也不能就说它是邪恶的呀

> to Azure_2003
> “多处使用Singleton服务器”是否经过严格的多用户并发性?> 测试,死锁等性能问题只有在大量并发用户操作才会出现。建
> 槭褂loadRunner测试一下,:) 呵呵


服务器已经使用几个月了没有重启过,用户虽然不是很多,但是也不少

> to Azure_2003
> “多处使用Singleton服务器”是否经过严格的多用户并发性?
> 测试,死锁等性能问题只有在大量并发用户操作才会出现。建
> 槭褂loadRunner测试一下,:) 呵呵


唔,人家的程序跑了N年还不算实践经验,非得拿loadrunner测过才算实践经验,这是哪门子的道理?这话听起来有点这味道:有人骑电动车上班,你说“电动车不安全,不信你到沪杭高速上跑个时速150,看它掉不掉链子。”

to gigix
我曾经向Azure_2003 请教过LoadRunner,你多发表点专业观点吧。

> to gigix
> 我曾经向Azure_2003
> 请教过LoadRunner,你多发表点专业观点吧。

那好,我就发表点专业观点。我现在批评Azure_2003了:你的application不能在0.5秒内响应请求,所以它实时性不强。你压根就不该用什么J2EE做什么web application,你应该用VC来做,才能保证实时性呢。Azure_2003笑了:拜托,我的用户根本就不需要那么高的实时性啊。

什么叫专业?作为职业软件开发者(而不是编程爱好者),满足用户的需求就是最大的专业。人家Azure_2003的application在那边run了几个月,用户100多天每天在那边用都没有抱怨,我们这些空口说白话的人倒在这里凭空抱怨,这难道是专业的态度吗?

哈哈,对,其实我们这里都是过嘴隐,软件测试有两种:功能测试和性能测试,我保证我做过的项目都亲自执行性能测试,包括JdonSD框架,但是实际项目中有多少真正做到呢?

就象Singleton模式,我掌握Piocontainer之前,项目很着急,没有时间研究Ioc容器怎么替代Singleton模式,还不是使用SIngleton模式上阵抗着,等以后重整,所以,还有网友问我,JiveJdon里为什么图片上传使用Singleton呢。

C++得指针,那么多人用错,为什么没有人说它邪恶?
面向对象那么多人无法用对,为什么没有人说它邪恶?
凡事都用两面,不能以偏概全,误导初学者。
很多人仍然在用goto。
没有绝对对的,也没有绝对错的。
以前大家都说Singlton好,现在觉得有些问题,就全盘否定,太幼稚。其实这些问题别人早就发现了,但人家还在用。只有我们这帮人还在把人家几年前讨认出结果的问题又翻出来。如果能够提出来一些新的思想来,也是好的,可是。。。
Spring也在用Singlton啊!使用Spring就可以抛弃Singlton了吗?二者动机和目的都不相同,面向的问题域也不同,无法完全取代对方。
使用模式必须有合理的动机和适当的方式。