[翻译] 单例(Singleton)
英文原文: https://sourcemaking.com/design_patterns/singleton
意图
- 确保一个类只有一个实例,并提供一个访问其实例的全局点;
- 封装 “即时初始化” (just-in-time initialization)或 “首次使用时初始化” (initialization on first use)。
问题
应用需要一个且唯一一个对象的实例。而且,延迟初始化(lazy initialization)和全局访问是必须的。
讨论
使得具有单一实例对象的类负责创建、初始化、访问和执行。声明这个实例作为一个私有静态数据成员。提供一个公共静态成员函数封装所有的初始化代码,同时提供对这个实例的访问。
任何时候,需要引用单一实例时,客户端(使用类名和范围精度操作符1)调用 accessor 函数。
只有满足所有下面三个标准时,才应该考虑单例模式:
- 单个实例的所有权不能合理分配;
- 延迟初始化是可取的;
- 全局访问未另行规定;
如果单个成员实例的所有权,何时以及如何初始化,全局访问都不是问题,那么单例模式将不足以令人感兴趣。
单例模式可以扩展到支持访问包含大量实例的具体应用。
“静态成员函数访问器”(static member function accessor)方法将不会支持 Singleton类的子类。如果需要子类,参考本书中的讨论。
删除一个Singleton类/实例是一个有意义的设计问题。可查看John Vlissides在讨论中所说 "To Kill A Singleton" 。
结构
使得包含单一实例的类负责访问和在第一次使用时初始化。这个单一实例是一个私有静态属性。而 accessor 函数是一个公共静态方法。
示例
Singleton 模式确保这种类只有一个实例,并提供此实例的全局访问点。它根据 singleton set 命名,singleton set 定义了一个只包含一个元素的集合。美国总统办公室就是一个单例。美国宪法指定总统的选举方式,限制了其任期,并定义了继任的顺序。所以,在任何给定时间,最多只有一个有效的总统。不管这个有效的总统的个人身份,这个标题 “美国总统” 是一个全局访问点,识别在办公室的那个人。
清单
- 在 “单一实例” 类中,定义一个私有静态属性。
- 在这个类中,定义一个公有静态 accessor 函数。
- 在访问器(accessor)函数中,进行 “延迟初始化”(在首次使用时创建)。
- 定义所有构造体为 protected 或 private 。
- 客户端可能只能使用 accessor 函数来操控 Singleton 。
经验法则
- Abstract Factory,Builder 和 Prototype 可以在它们实现中使用 Singleton 。
- Facade 对象常常是 Singletons,因为其只需要唯一一个 Facade 对象。
- 状态对象常常是 Singletons 。
- Singleton 对于全局变量的优势是当你使用 Singleton 时,你绝对确信实例的数目,而且你可以改变你的思维和管理任何数量的实例。
- Singleton 设计模式是最多被不恰当使用的模式之一。Singletons 只有在一个类必须只有一个实例,不能多,也不能少时,才能确定使用。设计者经常错误地使用 Singletons 替代全局变量。Singleton 出于意图和目的是一个全局变量。Singleton 并没有消除全局变量,它只是对其重命名。
- 什么时候 Singleton 是不必要的?简短的答案:大多数时候。长答案:当以引用的方式传递一个对象资源给需要它的对象更容易的时候,而不是让对象全局访问资源。对于 Singletons,真正的问题是它们给你一个好借口,不要仔细考虑一个对象的合适的可见性。发现在公开和保护对象之间合适的平衡,对于维护灵活性是非常重要的。
因为我们组有使用全局变量的坏习惯,所以我组织了关于 Singleton 的学习小组。接下来,我发现 Singletons 到处出现,而与全局变量相关的问题一个都没有消失。对全局数据的问题的答案并不是把它变成 Singleton 。其答案是 “到底你们为什么使用全局变量?” 改变名字不能改变问题。实际上,这样,可能会使情况变坏,因为你有机会说,“哦,我没有那样做,我是这样做的” —— 即使这样和那样是同一个事情。
代码示例
Java | Singleton in Java | Singleton in Java |
C++ | Singleton in C++: Before and after | Singleton in C++ |
PHP | Singleton in PHP | |
Delphi | Singleton in Delphi | |
Python | Singleton in Python |
译者注:
1、范围精度操作符 - scope resolution operator,即 "::"
[翻译] 单例(Singleton)的更多相关文章
- 跨应用程序域(AppDomain)的单例(Singleton)实现
转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...
- OpenJDK源码研究笔记(十三):Javac编译过程中的上下文容器(Context)、单例(Singleton)和延迟创建(LazyCreation)3种模式
在阅读Javac源码的过程中,发现一个上下文对象Context. 这个对象用来确保一次编译过程中的用到的类都只有一个实例,即实现我们经常提到的"单例模式". 今天,特意对这个上下文 ...
- spring mvc 的Controller类默认Scope是单例(singleton)的
使用Spring MVC有一段时间了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 说是因为线程安全问题,对于Spring MVC中bean默认都是(s ...
- 【Java学习笔记之三十】详解Java单例(Singleton)模式
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- 瞎扯设计模式1:单例模式 饿汉模式 懒汉模式 线程安全的单例 singleton 设计模式 java
[原创声明]此文为本人原创,欢迎转载,转载请注明出处,作者链接~ http://www.cnblogs.com/m-yb/p/8833085.html 单例很常用,面试也经常被问,如:不用自定义锁怎么 ...
- JAVA中实现单例(Singleton)模式的八种方式
单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 基本的实现思路 单 ...
- Lumen开发:lumen源码解读之初始化(3)——单例(singleton)与中间件(Middleware)
版权声明:本文为博主原创文章,未经博主允许不得转载. 今天来讲讲Lumen的singleton和Middleware,先来看看起始文件bootstrap/app.php / * | --------- ...
- 单例Singleton
先提供一个完整版: // .h文件 @interface SingleTon : NSObject /** 获取单例对象 */ + (instancetype)sharedInstance; + (i ...
- 设计一个线程安全的单例(Singleton)模式
在设计单例模式的时候.尽管非常easy设计出符合单例模式原则的类类型,可是考虑到垃圾回收机制以及线程安全性.须要我们思考的很多其它.有些设计尽管能够勉强满足项目要求,可是在进行多线程设计的时候.不考虑 ...
随机推荐
- 论文阅读 | CenterNet:Object Detection with Keypoint Triplets
相关链接 论文地址:https://arxiv.org/abs/1904.08189 代码链接:https://github.com/Duankaiwen/CenterNet 概述 CenterNet ...
- 通过securecrt跳板机登录linux服务器
1 需要开运维平台开通用户对某台服务器的访问权限: 2 使用自己的账号密码登录(sso账号密码) 登录后,需要输入一个服务器分配给每个人唯一的密码:
- Python 3.7版本关于json.dump失效
1.刚才写练习的时候,一直在报错,如图所示 2.度娘之后,才发现是因为我的文件名:json.py 与json.py冲突 所以该一个名字就ok了,如图所示
- [前后端分离项目]thinkphp返回给前端数据为字符串
写在前面:现在项目大多是采用前后端分离的模式进行开发,这种模式下的开发大大的提高了工作效率,而进行前后端数据交互传输的格式基本以json为主,毕业设计中兼顾前端开发和后端开发(后端小白一个),前端业务 ...
- 【python】-matplotlib.pylab常规用法
目的: 了解matplotlib.pylab常规用法 示例 import matplotlib.pylab as pl x = range(10) y = [i * i for i in x] pl. ...
- 【OpenCV-Python】-图像形态学转化
原文为段立辉翻译,感谢Linux公社此文档为自学转述,如有侵权请联系本人. 目标: • 学习不同的形态学操作,例如腐蚀,膨胀,开运算,闭运算等 • 学习的函数有:cv2.erode(),cv2.dil ...
- VSCode快捷键整理
shift+option+command+上下方向键 在上下方向增加或减少光标 shift+option+上下方向件 在复制当前行到下方或上方 位置跟方向键相反 shift+command+k 删除当 ...
- jQuery 学习笔记(jQuery: The Return Flight)
第一课. ajax:$.ajax(url[, settings]) 练习代码: $(document).ready(function() { $("#tour").on(" ...
- 国内Windows系统go get语言包
这时候我们需要设置代理.代理工具我推荐用 lantern https://github.com/getlantern/lantern 需要注意的是,它的代理地址是: http://127.0.0.1: ...
- solr的安装及配置详细教程/solr入门教程
1 solr的下载 从Solr官方网站(http://lucene.apache.org/solr/ )下载Solr最新版本,根据Solr的运行环境,Linux下需要下载solr-7.3.1.tgz, ...