博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[翻译] 单例(Singleton)
阅读量:7015 次
发布时间:2019-06-28

本文共 1945 字,大约阅读时间需要 6 分钟。

英文原文: 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在讨论中所说 "" 。

结构

使得包含单一实例的类负责访问和在第一次使用时初始化。这个单一实例是一个私有静态属性。而 accessor 函数是一个公共静态方法。

示例

Singleton 模式确保这种类只有一个实例,并提供此实例的全局访问点。它根据 singleton set 命名,singleton set 定义了一个只包含一个元素的集合。美国总统办公室就是一个单例。美国宪法指定总统的选举方式,限制了其任期,并定义了继任的顺序。所以,在任何给定时间,最多只有一个有效的总统。不管这个有效的总统的个人身份,这个标题 “美国总统” 是一个全局访问点,识别在办公室的那个人。

清单

  1. 在 “单一实例” 类中,定义一个私有静态属性。
  2. 在这个类中,定义一个公有静态 accessor 函数。
  3. 在访问器(accessor)函数中,进行 “延迟初始化”(在首次使用时创建)。
  4. 定义所有构造体为 protected 或 private 。
  5. 客户端可能只能使用 accessor 函数来操控 Singleton 。

经验法则

  • Abstract Factory,Builder 和  Prototype  可以在它们实现中使用 Singleton 。
  • Facade 对象常常是 Singletons,因为其只需要唯一一个 Facade 对象。
  • 状态对象常常是 Singletons 。
  • Singleton 对于全局变量的优势是当你使用 Singleton 时,你绝对确信实例的数目,而且你可以改变你的思维和管理任何数量的实例。
  • Singleton 设计模式是最多被不恰当使用的模式之一。Singletons 只有在一个类必须只有一个实例,不能多,也不能少时,才能确定使用。设计者经常错误地使用 Singletons 替代全局变量。Singleton 出于意图和目的是一个全局变量。Singleton 并没有消除全局变量,它只是对其重命名。
  • 什么时候 Singleton 是不必要的?简短的答案:大多数时候。长答案:当以引用的方式传递一个对象资源给需要它的对象更容易的时候,而不是让对象全局访问资源。对于 Singletons,真正的问题是它们给你一个好借口,不要仔细考虑一个对象的合适的可见性。发现在公开和保护对象之间合适的平衡,对于维护灵活性是非常重要的。

因为我们组有使用全局变量的坏习惯,所以我组织了关于 Singleton 的学习小组。接下来,我发现 Singletons 到处出现,而与全局变量相关的问题一个都没有消失。对全局数据的问题的答案并不是把它变成 Singleton 。其答案是 “到底你们为什么使用全局变量?” 改变名字不能改变问题。实际上,这样,可能会使情况变坏,因为你有机会说,“哦,我没有那样做,我是这样做的” —— 即使这样和那样是同一个事情。

代码示例

Java
C++
PHP
Delphi
Python

 

译者注:

1、范围精度操作符 - scope resolution operator,即 "::"

 

转载于:https://www.cnblogs.com/klchang/p/7354615.html

你可能感兴趣的文章
使用btrace需要注意的几个问题
查看>>
02hibernate_session
查看>>
问题汇总【4月】
查看>>
二次剩余
查看>>
Introduction of myself
查看>>
重温JS
查看>>
软件测试
查看>>
单选框,复选框
查看>>
[十二省联考2019]皮配(分类讨论的动态规划)
查看>>
Javascript:字符串分割split()妙用
查看>>
mysql远程连接权限设置
查看>>
iOS 项目调试
查看>>
微信小程序之回调函数
查看>>
C#中方法Show.和ShowDialog的使用区别
查看>>
没有找到suite objects.dll 因此这个应用程序未能启动
查看>>
使用wkhtmltopdf创建PDF文件
查看>>
Docker安装Jenkins
查看>>
leetcode653
查看>>
了解大数据
查看>>
001-对象——基础知识
查看>>