慎用单例模式!

简介:
   一年前曾经非常开心的修改了QQ签名,“酷爱单例模式”!
     经典设计模式书的第一讲,这是个如此神奇的模式,比C里的全局变量看起来更有过之而无不及,在任何地方,只要引用了库名称,你就能获得全局访问点,随时修改随时读取,岂不爽哉?
     于是,在一段时间内,我把我非常重要的几个实体类都用单例模式实现了,任何地方都可访问,解决了好多大难题!
     但,越到后来,越隐隐约约的发现,单例是个笑面杀手!
 
     对程序架构而言,单例意味着没有隐藏,插入到程序的任何组件都可以随时修改它,这客观上违背了面向对象的最小公开法则,程序健壮性安全性骤降。
     对程序扩展性而言,单例意味着很难被继承重写!  当你在一个单例中尝试覆盖它的某些功能时,编译器会报错,这时候你哭去吧。或者,你会奇怪的发现,咦?怎么还是基类的功能!
     对程序逻辑而言,单例,顾名思义,仅有其一,但你的程序在发展着,你确定只有一个实例即可?某天突然发现,业务变了,需要扩展,那些数不清的用单例调用的代码怎么处理?尤其是已经发布到顾客手中的代码?
     对效率而言,每次访问它的时候,都会查看是否被创建(多增加了一次判断),这对于一些需要高性能的程序是非常不合适的。
     对多线程而言,在多线程环境下,实现单例是需要技巧的。否则,单例不单!
     对对象生命周期而言,单例只有自己持有真正的引用,,如何销毁何时销毁都是问题,可能还会造成指针悬挂。
     对开发者而言,一个类不能new! 这还会带来更多的疑问和混淆。
 
     于是,我便站在了这样的十字路口,要么花大力气重写核心代码,要不延续单例模式的老路,再痛苦几年。
     痛定思痛, 我决定改掉那个模式。 大概,单例是个真正需求较窄的设计模式,仅仅适合设计配置参数上管理类,或者调试输出类(大家司空见惯的Log),或者是一些全局访问但功能相对单一的功能,千万别尝试将单例包装到复杂的数据实体上,这样做只是饮鸩止渴,哪天回过头来,就像操作系统的注册表一样,又臭又长,带来的危险比带来的好处还多得多!
     有一期“程序员”杂志刊登了一篇采访 GoF(设计模式作者)的文章,他们计划对<设计模式>进行修订,其中还特别提到要剔除“单例模式”,认为单例模式很容易在系统中产生“代码的臭味”,期待新版的设计模式早点出来。
     共勉。
相关文章
|
JSON 测试技术 数据处理
iOS-底层原理 35:组件化(一)方案
iOS-底层原理 35:组件化(一)方案
1428 0
iOS-底层原理 35:组件化(一)方案
|
Web App开发 Android开发 iOS开发
iOS 调试:通过 Safari/Chrome 调试 WebView
iOS 调试:通过 Safari/Chrome 调试 WebView
8315 0
iOS 调试:通过 Safari/Chrome 调试 WebView
|
域名解析 Ubuntu Linux
Docker 镜像基本操作
本文介绍 Docker 镜像最常用的三个基本操作 login、pull、push以及如何登录子账户。通过认识镜像的基本操作,您可以更熟练地使用容器镜像服务 ACR。
8122 0
Docker 镜像基本操作
|
网络安全 开发工具 git
git clone之报错git@gitee.com:Permission denied (publickey).fatal: Could not read from remote repository
git clone之报错git@gitee.com:Permission denied (publickey).fatal: Could not read from remote repository
1220 0
|
12月前
|
Shell 开发工具 git
上传文件到gitee(小白都能学会)
上传文件到gitee(小白都能学会)
2621 12
|
数据可视化 jenkins 测试技术
GitLab CI/CD 和 Jenkins对比
8月更文挑战第25天
1289 5
|
安全 Java 测试技术
阿里开发手册 嵩山版-编程规约 (五)日期时间的规范
《阿里开发手册 嵩山版》的日期时间规范部分提供了关于日期时间处理的强制性和推荐性规约,包括日期格式化、时间获取、避免硬编码日期、处理闰年问题等,以确保程序在时间处理上的准确性和稳定性。
|
编译器 Go Swift
【Swift开发专栏】Swift中的错误处理与异常捕获
【4月更文挑战第30天】Swift的错误处理机制通过遵循`Error`协议的类型定义和传播错误,以声明式方式捕获和处理问题。本文分为三部分:1) 错误定义与传播,包括自定义错误类型和使用`throw/try/catch`处理;2) 错误处理语法,如必须和可选捕获,以及错误传播;3) 实际应用中的最佳实践,如清晰定义错误、使用错误码和避免滥用错误处理。理解并熟练运用这些机制能提升代码的可靠性和可维护性。
357 1
|
存储 程序员 uml
【程序员必备】绘制架构图,流程图神器推荐
好的图形可以帮我们更好的表达自己,帮我们理清逻辑
|
Swift Perl
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
423 0