单例模式是设计模式的一种,由于其实现简单、易于使用,几乎为程序员必备模式,你问100个程序员,可能99个人都会用单例模式,但是,如果再让他们总结一下单例的弊端,那能脱颖而出的就没有几个了。
单例的生存期超长,会导致内存的持续占用。这是最常见的答案。
单例在多线程环境需要小心的处理线程互斥,进行资源保护。这是少数人可以给出的答案。
单例在类的继承树中不利于使用,会破坏继承体系。好吧,把单例用在继承中一般会来源于真实的代码经验,能遇到这个也不容易。
其实我认为最重要的一点是单例的全局可见性带来的设计破坏,不过能总结到这一条的人真得很少。下面就此问题多说几句。
曾几何时,看到过一个项目的代码,发现里面有大量的单例存在,在新功能的实现时,很多getInstance()的调用,假设这些单例的实现都是正确无误的,当看到大量getInstance()时,还是一个头两个大,耦合度太高,内聚性降低,整体的结构不清晰,到处是错综复杂的依赖,如果整理出类图,应该有剪不断理还乱的箭头线。这就是单例对设计的破坏,也可以认为是用单例代替设计。
单例的全局可见性使得单例的对象变成了全局变量,当我们还在面向过程的时代,我们的前辈就一再告诫我们一定要少用或不用全局对象,然后blabla列出一堆理由。到了面向对象的时代,全局变量的表现变少了,这条戒律也变淡了,虽然包装成了单例的形式,但那一堆理由是依然存在的。
我们在思考设计方案的时候,不再依托于业务本身,而是依托于一个代码技巧造就的单例进行设计,不再仔细平衡层次、结构,而是用了随手可以拿到的单例对象制造耦合。业务模型不重要了,层次关系不重要了,只要拿到一组单例对象,功能就实现了。这才是灾难,给维护带来的灾难,给重构带来的灾难,给可持续演进带来的灾难。
单例不是万能的,在带来了便利性的同时,也一定会伴随着很多弊端,切莫贪图一时的快捷而给项目埋下灾难的种子。
——欢迎转载,请注明原文出处 http://blog.csdn.net/caowenbin ——
——欢迎关注微信号“曹文斌的软件思考”,共同探讨软件人生——
——欢迎关注微信号“曹文斌的软件思考”,共同探讨软件人生——