首页 > 代码库 > [翻译] 单例(Singleton)
[翻译] 单例(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)