庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

singleton迷恋

Posted on 2008-02-23 15:34 dennis 阅读(2048) 评论(5)  编辑  收藏 所属分类: 模式与架构
    自从知道singleton模式这把锤子是什么样的之后,我就把很多小疙瘩也当成了钉子,时常想象偶顶着模式的光环挥舞着“万能”锤子在代码丛林中学习兰博搏斗的光辉形象~~~~。昨天读《重构与模式》的inline singleton一节,一句话点醒梦中人,singleton模式是“保证一个类仅有一个实例,并提供一个访问它的全局访问点”,原来——singleton也是全局变量啊。马教主深刻地教育过我们:全局变量在被证明无害之前都是有害。偶大汗淋漓。看看迷恋singleton的几种现象:
1、仅仅在一个地方调用到了某个singleton实例,并且对这个实例的处理代码也集中在这么一两个地方,这样的情况下你为什么要singleton?这里需要一个个全局访问点吗?我看你是为了singleton而singleton。

2、我为了性能优化啊!singleton只有一个实例,减小了创建开销。oh,我终于找到一个用singleton的充分理由了——性能。慢着,跟我读高大师的名言:“不成熟的优化是万恶之源”。你怎么知道singleton对象的重复创建是明显影响了性能?现代jvm对“短命”对象的创建代价已经非常低了。不成熟的优化不仅可能是无效的,而且也给以后重构工作带来了困难。除非有明显数据证明(分析工具而来)某个对象的重复创建是对性能影响极大,否则所谓性能优化不能成为采用singleton模式的理由。

3、有时候我们需要在系统的不同层次间传递一些共享信息,如果不采用singleton对象来提供这些共享信息,就得在调用的方法中重复地传递这些参数,这是个应用singleton模式的场景。但是,如果这些共享信息是可被修改的,或者说singleton对象不是无状态的,如果还采用singleton模式,那么你就不得不在调用的方法中从single对象取出旧信息和存入新信息,这样的重复代码将遍布的到处都是,不仅仅引入了同步访问的需要,而且出错的风险大大提高。这种情况下你还将这些信息作为方法参数传递而不是采用singleton可能更为清晰和健壮。

    singleton不仅仅是“保证一个类仅有一个实例”(这仅仅是描述),更重要的是它是用来“提供全局访问点”的(这才是它的功能),不要再迷恋这把锤子,好好利用这把锤子。

题外话:脚本语言似乎更容易滥用全局变量,javascript里可以模拟命名空间,Ruby也可以模拟类似的机制。最近写的一个比较大一点的Ruby脚本,用了几个全局变量(都是数组)用于保存状态数据,一开始没有意识到这一点,导致对全局变量的访问散落在好几个脚本文件里,RDT下看起来红通通的一片极其不爽。那么就重构吧——封装数组重构,将对这些全局数组的访问和修改操作统一到一个模块,调用全局变量的地方都引用这个模块,通过模块去操作全局变量,代码看起来清爽多了。



评论

# re: singleton迷恋  回复  更多评论   

2008-02-23 16:05 by 魔域私服
深有同感`

# re: singleton迷恋  回复  更多评论   

2008-02-23 16:46 by Jack.Wang
QQ 11843121
MSN(Email) wbjeasygo@163.com
技术与管理群 47763528

# re: singleton迷恋  回复  更多评论   

2008-02-23 21:29 by Arbow
哎呀,工作第一年的时候,用了N多singleton来做服务获取,用起来便利,但是发现做单元测试的时候一个字惨啊

# re: singleton迷恋  回复  更多评论   

2008-02-23 21:44 by Matthewchen
其实,全局变量,单例模式,和类的静态成员是不一样的。

# re: singleton迷恋  回复  更多评论   

2008-02-24 09:54 by dennis
@Matthewchen
貌似我没说一样

只有注册用户登录后才能发表评论。


网站导航: