索引

意图

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Ensure a class only has one instance, and provide a global point of access to it.

结构

参与者

Singleton

  • 定义一个 Instance 操作,允许客户访问它的唯一实例。Instance 是一个类操作。
  • 可能负责创建它自己的唯一实例。

适用性

在以下情况下可以使用 Singleton 模式:

  • 当类只能有一个实例并且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

缺点

  • 系统检查开销。实现中可能每次都需要检查实例是否存在,这个问题可以通过 Static 实例来解决。
  • 系统资源开销。通常 Singleton 中的对象一旦被创建,不会被及时销毁。可以通过提供 Reset 操作来重置。
  • 引起开发混淆。如果类包括 public 构造函数可以在外部构造,当使用 Singleton 对象时,开发人员需要记住不能使用 new 关键字来实例化对象。
  • 不易于测试。通常使用 Singleton 时需要考虑是否是反模式,设计是否存在问题。引入 Singleton 或静态实例会为 Unit Testing 带来困难。

效果

  • 对唯一实例的受控访问。
  • 缩小名空间。避免存储唯一实例的全局变量污染名空间
  • 允许对操作和表示的精化。Singleton 类可以有子类,通过扩展类在运行时刻配置应用。
  • 允许可变数目的实例。控制应用所使用的实例的数目。
  • 比类操作更灵活。比如使用静态成员函数。

相关模式

  • 很多模式可以使用 Singleton 模式实现。例如:Abstract Factory可以设计为 Singleton 实例。

实现

实现方式(一):使用 Static 变量初始化 Singleton。

在类加载时即创建实例。缺点是无论使用与否实例均被创建。

  1. namespace SingletonPattern.Implementation1
  2. {
  3. public class Singleton
  4. {
  5. private static Singleton _instance = new Singleton();
  6.  
  7. // the constructor should be protected or private
  8. protected Singleton()
  9. {
  10. }
  11.  
  12. public static Singleton Instance()
  13. {
  14. return _instance;
  15. }
  16. }
  17. }

实现方式(二):使用 Lazy Initialization 来实现 Singleton

通常将创建类的唯一实例的操作隐藏在一个类操作后面,由它保证只有一个实例被创建。这个操作可以访问保存唯一实例的变量,保证在它的首次使用前被创建和初始化。

  1. namespace SingletonPattern.Implementation2
  2. {
  3. public class Singleton
  4. {
  5. private static Singleton _instance;
  6.  
  7. // the constructor should be protected or private
  8. protected Singleton()
  9. {
  10. }
  11.  
  12. public static Singleton Instance()
  13. {
  14. if (_instance == null)
  15. {
  16. // use lazy initialization
  17. _instance = new Singleton();
  18. }
  19.  
  20. return _instance;
  21. }
  22. }
  23. }

实现方式(三):使用 Reset 来重置 Singleton

可以使用 Reset 操作来将已创建的实例销毁掉。

  1. namespace SingletonPattern.Implementation3
  2. {
  3. public class Singleton
  4. {
  5. private static Singleton _instance;
  6.  
  7. // the constructor should be protected or private
  8. protected Singleton()
  9. {
  10. }
  11.  
  12. public static Singleton Instance()
  13. {
  14. if (_instance == null)
  15. {
  16. // use lazy initialization
  17. _instance = new Singleton();
  18. }
  19.  
  20. return _instance;
  21. }
  22.  
  23. public void Reset()
  24. {
  25. _instance = null;
  26. }
  27. }
  28. }

实现方式(四):使用 Double-Check Locking 技术实现 Singleton

Singleton 的实现如果需要保证线程安全性,则可以使用 Double-Check Locking 技术。

  1. namespace SingletonPattern.Implementation4
  2. {
  3. public class Singleton
  4. {
  5. private static Singleton _instance;
  6. private static readonly object _syncRoot = new object();
  7.  
  8. // the constructor should be protected or private
  9. protected Singleton()
  10. {
  11. }
  12.  
  13. public static Singleton Instance()
  14. {
  15. // double-check locking
  16. if (_instance == null)
  17. {
  18. lock (_syncRoot)
  19. {
  20. if (_instance == null)
  21. {
  22. // use lazy initialization
  23. _instance = new Singleton();
  24. }
  25. }
  26. }
  27.  
  28. return _instance;
  29. }
  30. }
  31. }

实现方式(五):使用注册表机制创建和查询 Singleton 类的子类实例

如果系统中定义了多个 Singleton 的子类,可以实现一个注册表机制,用于存储子类的映射。

  1. namespace SingletonPattern.Implementation5
  2. {
  3. public class Singleton
  4. {
  5. private static Dictionary<string, Singleton> _registry
  6. = new Dictionary<string, Singleton>();
  7. private static Singleton _instance;
  8.  
  9. // the constructor should be protected or private
  10. protected Singleton()
  11. {
  12. }
  13.  
  14. public static Singleton Instance(string name)
  15. {
  16. if (!_registry.ContainsKey(name))
  17. {
  18. if (name == "Apple")
  19. {
  20. _registry.Add(name, new AppleSingleton());
  21. }
  22. else if (name == "Orange")
  23. {
  24. _registry.Add(name, new OrangeSingleton());
  25. }
  26. }
  27.  
  28. return _registry[name];
  29. }
  30. }
  31.  
  32. public class AppleSingleton : Singleton
  33. {
  34. }
  35.  
  36. public class OrangeSingleton : Singleton
  37. {
  38. }
  39. }

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Singleton(单件)的更多相关文章

  1. C#面向对象设计模式纵横谈——2.Singleton 单件(创建型模式)

    一:模式分类 从目的来看: 创建型(Creational)模式:负责对象创建. 结构型(Structural)模式:处理类与对象间的组合. 行为型(Behavioral)模式:类与对象交互中的职责分配 ...

  2. 设计模式之美:Creational Patterns(创建型模式)

    创建型模式(Creational Patterns)抽象了对象实例化过程. 它们帮助一个系统独立于如何创建.组合和表示它的那些对象. 一个类创建型模式使用继承改变被实例化的类. 一个对象创建型模式将实 ...

  3. 设计模式之美:Null Object(空对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...

  4. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  5. 设计模式之美:State(状态)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):由 ConcreteState 指定它的后继 State. 意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改 ...

  6. 设计模式之美:Facade(外观)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):用抽象类定义 Facade 而使子类对应于不同的子系统. 意图 为子系统中的一组接口提供一个一致的界面,Facade 模式定义了 ...

  7. 设计模式之美:Abstract Factory(抽象工厂)

    索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):使用 Factory Method 来实现 Abstract Factory. 实现方式(二):使用 Pr ...

  8. 《设计模式之美》 <03>面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?

    面向对象 现在,主流的编程范式或者是编程风格有三种,它们分别是面向过程.面向对象和函数式编程.面向对象这种编程风格又是这其中最主流的.现在比较流行的编程语言大部分都是面向对象编程语言.大部分项目也都是 ...

  9. 设计模式之单例模式——Singleton

                        设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...

随机推荐

  1. 25、继续echarts实现中国地图

    1. 以上是实现的效果 下边是实现的代码,上一篇地图没有颜色,是因为没有引入zrender包,因为echarts画地图是基于zrender实现的 <!DOCTYPE html> <h ...

  2. System.ArgumentOutOfRangeException: 指定的参数已超出有效值的范围

    GridView指定的参数已超出有效值的范围GridView在更新过程中异常详细信息: System.ArgumentOutOfRangeException: 指定的参数已超出有效值的范围.参数名:v ...

  3. mysql - 最小缺失值查询

    初始化数据 DROP TABLE IF EXISTS X; CREATE TABLE X( a INT UNSIGNED PRIMARY KEY, b ) NOT NULL )ENGINE=INNOD ...

  4. spring 下载地址

    http://repo.spring.io/release/org/springframework/spring/

  5. java 链接jdbc

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  6. nginx 设置反响代理实现nginx集群

    ginx.conf: worker_processes  1; events { worker_connections  1024; } http { include       mime.types ...

  7. Python_sklearn机器学习库学习笔记(一)_Feature Extraction and Preprocessing(特征提取与预处理)

    # Extracting features from categorical variables #Extracting features from categorical variables 独热编 ...

  8. Linux系统编程-setitimer函数

    功能:linux系统编程中,setitimer是一个经常被使用的函数,可用来实现延时和定时的功能. 头文件:sys/time.h 函数原型: int setitimer(int which, cons ...

  9. iconv命令 gbk 转 UTF-8

    -----linux gbk 转 UTF-8-------- iconv 用法 iconv -f "gbk" -t "utf-8" < infile &g ...

  10. 如何使用JS脚本从HTML中分离图片标签与文本,替换文本中指定的内容并加粗(原创)

    var html='ddfsdfsdfdsd dfsdfsdffds<img _src="http://localhost:8490/60E86EA7-FE7B-44BF-8270-4 ...